Прямоугольные массивы двумерных символов в C ++ - PullRequest
1 голос
/ 17 февраля 2012

Я использую двумерные символьные массивы для хранения нескольких строк. Код ниже отлично работает и выводит правильные строки.

    char str[3][4];

    std::cin >> str[0] >> str[1] >> str[2] >> str[3];

    std::cout << str[0] << '\n' << str[1] << '\n' << str[2] << '\n' << str[3];

но , когда я пытаюсь это сделать

    char str[3][3];

    std::cin >> str[0] >> str[1] >> str[2];

    std::cout << str[0] << '\n' << str[1] << '\n' << str[2];

Тогда, если я введу

abc

xyz

pqr

я получаю вывод

abcxyzpqr

xyzpqr

pqr

Какое может быть возможное объяснение?

Ответы [ 4 ]

4 голосов
/ 17 февраля 2012

Причина в том, что строки C заканчиваются нулем.Это означает, что они рассматриваются как завершающиеся, когда встречается первое вхождение нулевого символа ('\ 0', значение 0).

Когда вы вводите трехсимвольную строку "abc" в строку str [0], это будет представлено в памяти как {'a', 'b', 'c', '\ 0'}.Четыре символа, последний из которых является нулевым терминатором.

Этот нулевой терминатор затем перезаписывается следующим вводом, поскольку str [0] является строкой из 3 символов, и, таким образом, нулевой терминатор будет записан в str [0] [3], что эквивалентно str [1] [0].

4 голосов
/ 17 февраля 2012

Размер ваших строк 3, и вы вводите 3 символа. Это означает, что он не получает места для хранения нулевого символа \0 и, следовательно, не может найти конец строки.

3 голосов
/ 17 февраля 2012

Это потому, что вы выделяете 3 char s для каждой строки, и они имеют длину 3 - поэтому в конце строки нет \0. Строки C ++ должны заканчиваться \0 для обозначения конца. Когда выделяется 4 char s, C ++ автоматически дополняет каждую строку символом \0. Безопасно создавать массивы, по крайней мере, n+1 char с, когда вам нужно хранить не более n char с.

Кажется, что все 9 char s из str являются смежными, поэтому первая строка имеет длину 9. Оператор cout идет для вывода из str[0][0], и, поскольку \0 в конец str[0], он продолжает печатать str[1] и str[2].

2 голосов
/ 17 февраля 2012

Эти строки называются '0-terminated', потому что литеральная строка в C - это последовательность символов, оканчивающаяся на 0 (нулевой байт).

Вы переполняете терминатор первым символомпоследовательной строки.

Остерегайтесь неопределенного поведения.

...