GargantuChet правильно объяснил, почему вы получаете 'a's.
В общем, есть много других проблем
1 for (;;)
2 {
3 char ch;
4 if (cin.fail()) break;
5 cin.read((char*)&ch, sizeof(unsigned char));
6 cout << hex << (unsigned int)(unsigned char)ch < <endl;
7 cin.clear();
8 }
В строке 4 вы видите, установлена ли cin.fail()
, нос потоками они никогда не запустятся в состоянии сбоя - вы должны попытаться сделать что-то, чтобы это не удалось.Другими словами, вы должны сделать read()
, а затем взглянуть на cin.fail()
.В общем, вы также должны использовать gcount()
, чтобы проверить, сколько байтов действительно может быть прочитано (например, несмотря на запрос, скажем, 4, вы можете получить только 2, что не будет считаться ошибкой), но здесь вы запрашиваете только 1символ, так что это может быть проще.
Очистить его немного, но придерживаясь того же основного подхода:
1 for (char ch; cin.read(&ch, sizeof ch); )
2 cout << hex << (unsigned)(unsigned char)ch < <endl;
Это работает, потому что read()
возвращает ссылку на cin
и оценку«истина» cin
является сокращением для запроса о том, был ли введенный до сих пор ввод без ошибок (более строго, по крайней мере, с момента последнего clear()
, если вы его используете).
Тем не менее, std::istream
, из которых std::cin
является экземпляром, также имеет функцию, предназначенную для получения символов, позволяющую упростить цикл до:
for (char ch; std::cin.get(ch); )
...
В стороне
Помните, что for( ; ; )
оператор управления состоит из трех частей:
- код инициализации слева, который также может создавать новые переменные
- тест: это происходит до 1-го и каждогопоследующее выполнение оператора (ов) цикла
- кода, который будет выполняться только после каждого выполнения оператора (ов) и перед повторением теста.
Из-за этого такие тесты, как std::cin.get(ch)
, вызываются и оцениваются на предмет успеха как условие для каждой итерации.Последнее решение, указанное выше, эквивалентно:
{
char ch;
while (std::cin.get(ch))
...
}