У меня есть несколько вопросов, которые я хотел бы уточнить о cstrings:
1) Инициализация:
При объявлении массива символов следующим образом, C ++ автоматически определяет его как cstring? или (как я считаю) массив символов?
char a[10];
Другими словами, это массив символов, содержащий только нулевой терминатор (‘\ 0’), или это пустой массив символов?
2) При работе непосредственно с индексами cstring (i.e. a[i] = ch+1;
), cstring автоматически заботится о своем нулевом терминаторе, или это обязанность программиста оставить для него место и вставить его?
Пример кода (это то, что я считаю правильным ответом):
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) При использовании <cstring>
библиотека (например, strncpy, strncat и т. д.), заботится ли она о нулевом терминаторе? Пример:
char myCstring[] = "I am a cstring"; //size of 15 (including '\0' at i == 14)
strncpy(myCstring, "I am NOT a string object", 14);
Приведет ли это к следующему массиву?
| 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
И наконец:
char myCstring[] = "I am a cstring"; //size of 15 (including '\0' at i == 14)
strncpy(myCstring, "I'ma cstring", 14);
Приведет ли это к следующему массиву?
| 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
Простите за беспорядок.
1) Это массив chars
которые обычно являются 8-битными целыми числами.
2) Нет, он рассматривается как массив — все работает точно так же, как и для массива целых.
3) Многие считают strncpy
быть небезопасным — он добавляет символ ‘\ 0’ в конце строки, но не когда строка усекается, как в вашем случае. Результирующий массив будет выглядеть так:
| 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
Трейлинг ‘\ 0’ не будет, если вы пройдете 15
хотя для размера он существует только потому, что функции сообщили, что массив завершился на 1 символ. Если вы прошли sizeof(myCstring)
по размеру вывод будет другим:
| 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
Обратите внимание на отсутствие завершающего символа ‘\ 0’, который может вызвать ошибку сегментации при попытке чтения строки (но в некоторых случаях этого не требуется, что затрудняет отладку).
4) Да, как объяснено в пункте 3.