Ignorando EOF em std :: cin em C ++
Pergunta
Eu tenho um aplicativo que implementa um shell interativo, semelhante à forma como o console Python / obras IRB. O problema agora é que, se o usuário pressiona acidentalmente ^D
EOF é emitido e minha chamada getline()
retorna uma string vazia que eu tratar como "sem entrada" e exibir o prompt novamente.
este então resulta num anel sem fim que imprime a linha.
Agora, em Python que eu iria resolver esse problema pela captura EOFError
, mas em C ++ nenhuma exceção é gerada eu poderia pegar e não parece ser um ajuste no cin
ignorar EOF.
Alguma dica?
Solução 2
Corrigir solução graças a litb:
if (!getline(std::cin, str)) {
std::cin.clear();
std::cout << std::endl;
}
Outras dicas
Se ele não conseguia ler nada, ele define o failbit
. Apenas testar o fluxo em uma condição if, e limpar o bit:
if(!getline(std::cin, myline)) {
std::cin.clear();
std::cout << "you should enter something" << std::endl;
}
Internamente, a sequência é desta forma no seu caso:
- Espera no terminal para uma string. Terminal será bloqueado até que o utilizador emite uma nova linha. Dois casos de erro prováveis ??possíveis
- usuário pressiona imediatamente EOF. Isso fará com que
getline
leitura absolutamente nada, e ele irá definir ofailbit
eoeofbit
. - Usuário entradas alguma coisa e, em seguida, pressiona EOF. Isso fará com que
getline
consumir alguma coisa e, em seguida, ela atinge EOF ao tentar obter o próximo caractere. Esta causaeofbit
a ser definido.
- usuário pressiona imediatamente EOF. Isso fará com que
- Você vai tentar ler algo novo. A função de extração criará um objeto do tipo
istream::sentry
que cheques em que estado o fluxo é. Se algum dos errorbits está definido, ele fará com que a função de extração para retornar imediatamente. Isso fez com que o loop infinito antes.
Uma chamada para clear()
limpa todos os bits de erro, e você pode continuar lendo suas coisas novamente.
getline()
sinais de função erros usando os seguintes bits:
- eofbit
- failbit
- badbit
Tente verificar estes antes de prosseguir.
http://www.horstmann.com/cpp/pitfalls.html
Você pode usar o código como:
while (cin)
{ int x;
cin >> x;
if (cin) a.push_back(x);
}
Ok, em outras respostas usando cin.clear () foi descrita como uma solução possível.
Outro truque é que você use outros meios para processar a entrada do console do que o padrão típico em definindo o terminal para outro modo que você possa processar Ctrl + D diretamente. No modo RAW ou outros, obtém acesso mais directo para as sequências de entrada e de controlo a partir do lado do utilizador (como Ctrl + D ou Ctrl + C) não são tratadas elswhere mais.
Algumas bibliotecas que você pode tentar recolher mais informações (ou até mesmo economizar tempo de codificação):
- GNU Readline
- Útil Terminal I / O Biblioteca ½
- NCurses (que é muito poderoso)
½ Você pode encontrar algumas informações sobre o seu problema na documentação aqui .