С++ cin.get(), cin.peek() приостанавливается, то же самое с stdio

Это мой код, как он есть в настоящее время. Этот код выдает ошибку в cin.get(). Я понимаю, что это плохой код, он никогда не должен был быть таким, я просто тестировал некоторые вещи.

#include <string>
#include <iostream>
#include <stdio.h>

using namespace std;

int main(){
    char c[1000];
    cin.setstate(cin.eofbit);
    cout << cin.good() << endl;
    cout << cin.eof() <<endl;
    cout << cin.get() << endl;
    cin.putback('c');
    cout << cin.get() << endl;
    cout << "Do we ever reach this?" << endl;
    while(1){
    };
    return 0;
}

Так или иначе. Моя проблема заключается в том, что cin.get(), cin.peek(), cin.ignore(), getchar() или почти любая функция cin или stdio, которую вы можете назвать, приостанавливает выполнение моей программы, когда поток пуст, без установки Биты EOF или что-то еще. Меня это раздражает, так как я хочу проверить, есть ли что-нибудь в потоке, чтобы очистить его, так как ignore() всегда делает паузу.

Единственный метод, который я могу заставить работать, — это «istream::readsome». Я загрузил это в массив символов и распечатал с помощью cout. Он печатает длинную строку символов, которые я не узнаю (каждый из них является отдельным символом).

http://gyazo.com/e3ee65cdad7ed5cc7b2ce2307ca58c90

При преобразовании к целому числу они получаются как -52, что не соответствует чему-либо ни в ASCII, ни в Unicode.

Я компилирую с помощью Visual C++ Express 2010.

Пожалуйста, помогите, я совершенно запутался в этом вопросе. Я просто хочу читать символы/сбрасывать мой поток, не останавливаясь, если там ничего нет. Я потратил добрых 3 часа, пытаясь решить эту проблему. Вздох.


person user1819357    schedule 12.11.2012    source источник
comment
sync() отбрасывает все, что осталось в буфере, но такое поведение не гарантируется.   -  person chris    schedule 13.11.2012
comment
Спасибо, посмотрю. Но есть ли какой-нибудь гарантированный способ или способ предотвратить ужасную паузу, если я СДЕЛАЮ cin.ignore или cin.peek?   -  person user1819357    schedule 13.11.2012
comment
OTOH, правильно проверяя результаты ваших операций ввода-вывода, вы никогда не должны доходить до точки, когда вы не знаете, пуст ли поток или нет.   -  person jrok    schedule 13.11.2012
comment
Но я не уверен, как я могу правильно проверить, если я не могу проверить, что осталось в потоке, не приостановив случайно мою программу. Кроме того, он все равно должен установить бит EOF, не так ли? Это просто не устанавливается.   -  person user1819357    schedule 13.11.2012
comment
Чтобы установить бит EOF из консоли, введите Ctrl + Z.   -  person Jesse Good    schedule 13.11.2012
comment
Это не то, что я имею в виду, хотя Джесси. Когда я пытаюсь извлечь символ из пустого потока, а не устанавливаю бит EOF (как сказано на cplusplus.com), он ждет ввода. Даже когда я смотрю только на следующего персонажа.   -  person user1819357    schedule 13.11.2012
comment
@ user1819357: Верно, это то, что он должен делать (хотя я не знаю, что говорит cplusplus.com). Я не понимаю, почему std::getline и std::string было бы недостаточно.   -  person Jesse Good    schedule 13.11.2012
comment
Похоже, что они должны быть, я просто хотел получить дополнительную гибкость, обеспечиваемую возможностью попытаться прочитать поток, не захватывая всю программу. Imalso просто пытается понять, почему его, казалось бы, плохое поведение. Может проблема в компиляторе?   -  person user1819357    schedule 13.11.2012


Ответы (1)


Чтобы избавиться от всех доступных символов, вы можете использовать std::istream::ignore() в сочетании с std::streambuf::in_avail():

std::cin.ignore(std::cin.rdbuf()->in_avail());

Однако я предполагаю, что на самом деле это не делает то, что вы хотите: стандартные потоковые объекты просто читают то, что им передает операционная система. Как правило, режим по умолчанию для ввода, подключенного к какому-либо окну консоли, заключается в линейной буферизации ввода. Сколько символов действительно передается потоку, в значительной степени не определено.

Чтобы проверить, доступен ли ввод во входном потоке, вам необходимо использовать методы, специфичные для платформы. Стандартная библиотека C++ не обеспечивает неблокирующей проверки поступления новых данных std::cin. В системе POSIX вы можете просто использовать poll() с файловым дескриптором 0, чтобы узнать, есть ли у std::cin какие-либо данные. Что нужно в системах, отличных от POSIX, я не знаю.

person Dietmar Kühl    schedule 12.11.2012
comment
У меня была возня с этим. IN_avail всегда возвращал 1, независимо от того, сколько символов я помещал в cin. . Кроме того, единственный способ очистить его был с помощью sync(). Плюс игнор решает поставить вещи на паузу, вздох. Тем не менее, спасибо за ответ, я буду продолжать искать что-то, что может проверить это в Windows. - person user1819357; 13.11.2012
comment
@user1819357 user1819357 вы нашли способ проверить Windows? - person Thomas Ibbotson; 05.08.2019