Почему объект cout игнорирует нулевой символ?
Изучаю С++ две недели. Подскажите пожалуйста, в моей логике при вводе строковой константы, например "animal" в оператор cin
, данная константа помещается в массив и естественно автоматический символ \0
помещается тоже.
Однако при выполнении цикла, cout
всё-таки отображает ВСЮ строку (посимвольно в обратном порядке). Но я же указал СПЕЦИАЛЬНО в переменной i
(не добавлял -1), чтобы первый символ, который он выводит, это как раз таки символ \0
.
Индекс массива соответствует [6], а моё слово с учётом начала индексации массива начиная с [0] хранится с 0 по 5 ячейку. То есть в 6 будет нулевой символ, так собственно почему объект cout
выводит в любом случае всё слово, ведь для него ноль - это значит стоп.
int main()
{
cout << "Enter a word:";
char word[ArSize];
cin >> word;
for (int i = strlen(word); i >= 0; i--)
cout << word[i];
Ответы (2 шт):
Для начала отвечу на кликбейтный заголовок, раз уж я на него повёлся.
Нет, объект std::cout
ни в коем разе не игнорирует нулевой символ. Он его нормально выводит.
null.cpp:
#include <iostream>
#include <string>
using namespace std::string_literals; // since C++14
int main() {
std::cout << '\0';
// std::string s("ab\0\0cd", 6);
std::string s = "ab\0\0cd"s; // since C++14
std::cout << s << std::endl;
return 0;
}
Работает примерно так:
$ c++ --std=c++14 null.cpp && ./a.out > null.out && ls -l null.out && od -c null.out
-rw-r--r-- 1 leo staff 8 4 ноя 22:46 null.out
0000000 \0 a b \0 \0 c d \n
0000010
Как бы, видно, что нулевой символ нормально выдаётся, как при выдаче char
, так и при выдаче std::string
.
А так же, в C++ всё хорошо работает и для всех иных видов строк C++: std::wstring
, std::u32string
, std::u16string
и std::u8string
(при использовании std::wcout
или иных способов).
Другое дело, что для строк C символ '\0' является ограничителем. Поэтому до C++14, в котором появились литералы C++ строк, работа с нулевым символом была несколько затруднена.
Что касается вашего кода, то он тоже нормально выводит нулевой символ:
$ c++ test.cpp && echo WORLD | ./a.out > test.out && ls -l test.out && od -c test.out
-rw-r--r-- 1 leo staff 19 4 ноя 22:54 test.out
0000000 E n t e r a w o r d : \0 D L
0000020 R O W
0000023
Видно, что на ввод "WORLD", он выводит нулевой символ и "DLROW".
Поскольку всегда верно s[strlen(s)] == '\0'
, по определению C-строк (символ '\0' не входит в состав C-строки).
'\0'
останавливает печать строки только если печатается char*
. Если печатать символы под одному (тип char
), то все они будут напечатаны. Символ '\0'
печатается как пустое место. Не пробел, а пустое место. Его не видно на экране.
#include <iostream>
int main() {
std::cout << '[' << '\0' << ']' << '\n';
}
Вроде бы нуля нет:
$ g++ temp.cpp $ ./a.out []
Но он есть. Напечатано четыре символа, wc
их считает и od
их видит, включая ноль:
$ ./a.out | wc -c 4 $ ./a.out | od -c 0000000 [ \0 ] \n 0000004