O cenário é: inserir inteiros e caracteres alternadamente e lê-los em variáveis do tipo correto. Adotei a abordagem mais direta: ler de qualquer maneira como se fossem todos inteiros; em caso de falha, redefinir os sinalizadores cin e ler como caracteres.
int a;
char c;
while (true) {
cin >> a;
if (cin.fail()) {
if (cin.eof()) {
cout << "eof" << endl;
break;
}
cin.clear();
cin >> c;
cout << "fail: " << c << ": " << int(c) << endl;
}
else {
cout << "success: " << a << endl;
}
}
Funciona perfeitamente, exceto pelos dois caracteres: +
, -
. Por exemplo, quando você insere 2 4 + 5 *
, a saída seria:
success: 2
success: 4
fail: 5: 53
fail: *: 42
eof
Para *
, funciona; mas para +
, parece que +
se perde e 5
é lido. Fiz alguns testes sozinho (por exemplo, usando cin.get()
instead) e descobri que: após cin >> a
falha ao encontrar +
, +
é consumido e a posição do fluxo aponta para o espaço entre +
e 5
.
O que torna +
um caractere -
especial? Após algumas pesquisas, acredito que o motivo possivelmente seja: quando cin
se espera um número inteiro, o caractere +
ou -
que ele encontra é aceito como um possível prefixo de números inteiros como +5, -3, etc. Isso leva ao fato de que ele +
é consumido, em vez de permanecer no fluxo de entrada como outros caracteres.
Como você interpreta o problema? Como corrigir o código para que ele funcione corretamente?
PS: Sei que uma solução alternativa é ler todas elas como strings e depois fazer uma análise mais aprofundada. Só estou curioso para saber se é possível modificá-las com base na abordagem original. Dessa forma, eu poderia ser mais claro sobre os mecanismos por trás de cin
.
Acho que este post já pode ser encerrado. Obrigado por todos os comentários e respostas. As opiniões e conselhos que vocês compartilharam são muito apreciados, com os quais aprendi muito.
Como eu disse, não se trata de uso prático e, em primeiro lugar, não estou procurando uma solução completa. Na prática, certamente adotarei as abordagens baseadas em strings sugeridas por você. É apenas um pequeno problema que encontrei, e depois decidi fazer uma breve digressão e brincar um pouco com a questão.
Quanto à questão que levantei, ou seja, corrigir o código, aprendi um pouco com as respostas abaixo e a documentação oficial. Usar funções como essa cin.putback() cin.peek() cin.tellg() cin.seekg()
ajudará a resolver o problema.