Почему объект 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 шт):

Автор решения: Serge3leo

Для начала отвечу на кликбейтный заголовок, раз уж я на него повёлся.

Нет, объект 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-строки).

→ Ссылка
Автор решения: Stanislav Volodarskiy

'\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
→ Ссылка