-1

I have a few questions I would like to clarify about cstrings:

1) Initialization: When declaring an array of characters as follows, does C++ automatically defines it as a cstring? or (as I believe) an array of characters?

char a[10];

In other words, is this an array of characters containing only a null terminator ('\0') or is it an empty array of characters?

2) When working directly on a cstring's indexes (i.e. a[i] = ch+1;), does a cstring automatically takes care of its null terminator, or is it the programmer's responsibility to leave space for it and insert it?

Example code (This is what I believe to be the right answer):

char a[10];
int i = 0;
cin.get(ch);

while(ch != '\n' || i < 9) {
    a[i] = ch;
    counter++;
    cin.get(ch);
}
a[i] = '\0';    //either the last index(9) 
                //or the one right after the
                //last input will be set to '\0'

3) When using the <cstring> library (like strncpy, strncat, etc.), does it take care of the null terminator? Example:

char myCstring[] = "I am a cstring";  //size of 15 (including '\0' at i == 14)
strncpy(myCstring, "I am NOT a string object", 14);

Will this result in the following array?

| I |   | a | m |   | N | O | T |   | a |   | s | t | r | '\0' |
  0   1   2   3   4   5   6   7   8   9  10  11  12   13   14

And lastly:

char myCstring[] = "I am a cstring";  //size of 15 (including '\0' at i == 14)
strncpy(myCstring, "I'ma cstring", 14);

Will this result in the following array?

| I | ' | m | a |   | c | s | t | r  | i | n | g | '\0' |x|x|
  0   1   2   3   4   5   6   7   8    9   10  11   12  13 14

Sorry for the mess.

Gil Dekel
  • 355
  • 4
  • 15
  • One question per question, please. – Veedrac Dec 14 '14 at 01:47
  • 3
    C and C++ don't have any formal concept of a "C-string"; a C-string is nothing more than an array of characters with a 0 byte placed after the last valid character in the string. – Jeremy Friesner Dec 14 '14 at 01:51
  • 1
    @remyabel: What's commonly called a "cstring" is what the C standard calls a "string". It is by definition "a contiguous sequence of characters terminated by and including the first null character". A string literal is something else; it's a construct in C or C++ source code, whereas a string is something that exists during program execution. – Keith Thompson Dec 14 '14 at 02:05

1 Answers1

1

1) It is an array of chars which are usually 8bit integers.

2) No, it is treated as an array - everything works exactly the same way as it would for an array of ints.

3) Many people consider strncpy to be unsafe - it does add a '\0' character at the end of the string, but not when the string is truncated, similar to your case. The resulting array would look like so:

| I |   | a | m |   | N | O | T |   | a |   | s | t | r | '\0' |
  0   1   2   3   4   5   6   7   8   9  10  11  12   13   14

The trailing '\0' wouldn't be there if you passed 15 for the size though, it is there only because the function was told the array has ended 1 character short. If you passed sizeof(myCstring) as size, the output would be different:

| I |   | a | m |   | N | O | T |   | a |   | s | t | r | i |
  0   1   2   3   4   5   6   7   8   9  10  11  12   13  14

Notice the lack of a trailing '\0' which can cause a segmentation fault when you try reading the string (but doesn't have to in some cases which makes it harder to debug).

4) Yes, as explained in point 3.

Kelm
  • 967
  • 5
  • 14
  • So, it will place a `'\0'` one location after the limit argument (even if it passes the array's size), or the last character when the `string_argument < sizeOfArray`?? – Gil Dekel Dec 14 '14 at 01:58
  • No, it will omit it completely if there is not enough space to copy the whole string. In this case you won't notice this because the last character is already '\0' and you pass `size - 1` as the array size. I edited and hopefully made it a bit more clear. – Kelm Dec 14 '14 at 02:04
  • ok, so what happenes when the string_argument is smaller then the size of the array? As in my second example ("I'ma cstring")? Will the null terminator be placed right after the last character of the input is inserted? or will it be placed at mentioned limit argument? – Gil Dekel Dec 14 '14 at 02:13
  • Yes. That's why the function is not safe at all, it's easy to forget about this weird behaviour. It originated long ago in Unix file system I think. – Kelm Dec 14 '14 at 02:20
  • 1
    The problem is that `strncpy` is not what most people think it is. It's not a length safe `strcpy`. The `strncpy` function is a fixed width string copy function meant for use in things like database files. When you write these strings to a stream it's expected you'll output the same number of characters every time, and read the same number in every time. So that string is either the full length or is padded with NUL. Problem is that nobody uses it for this, they use it as a length safe `strcpy` and that's just not what it is. – Edward Strange Dec 14 '14 at 02:22
  • But if you consider the one extra space needed for the null terminator, it is safe to assume an `'\0'` will be added after the last char input, as I did for my first example, correct? To sum this up, a null terminator will be added as long as it has space? Also, what happens if you `strncpy` and "accidentally" pass the limit? (e.g. `char arr[10]; strncpy(arr, "I am NOT a string!", 18)` will this result in writing over memory locations outside the array? just like any other array, and then place a null terminator at arr[18]? (even though it's out of bound) – Gil Dekel Dec 14 '14 at 02:29
  • In the first example it is not added, it is already there. An array in C is nothing more than a pointer, the size of an array is unknown at runtime (unless you store that information somewhere yourself). C is not an interpreted language like Java or C# to have all those fancy (and slow compared to C) features. – Kelm Dec 14 '14 at 03:33