paulo1205
(usa Ubuntu)
Enviado em 01/05/2015 - 10:13h
A causa do problema é que, após ler o valor numérico com o operador
>>, o sinal de fim de linha (
'\n') não é consumido, e acaba sendo lido pelo
getline seguinte, como se fosse uma linha vazia. Você tentou tratar isso usando
__fpurge(), mas aparentemente
std::cin e
stdin não estão compartilhando exatamente os mesmos dados (i.e. o
'\n' já deve estar no buffer de
std::cin, e não mais no de
stdin).
Em todo caso, não é mesmo prudente misturar E/S ao estilo de C com ao estilo C++ pois, embora haja alguma tentativa de sincronizar as duas, isso não é obrigatório para toda e qualquer implementação, e mesmo aquelas que tentam fazê-lo podem não alcançar um nível perfeito -- como você bem pôde ver neste caso. Por isso, minha sugestão é que você use funções do C++ para administrar o estado da entrada.
Um bom ponto de partida é usar a função membro
std::istream::ignore(). Outras possibilidades que me ocorrem são:
1) Fazer e usar uma função específica para descarte, que ao contrário de
std::istream::ignore(), não descarte simplesmente todos os caracteres, mas somente espaços em branco que não sejam
'\n'. Essa função poderia parecer com o que vai abaixo.
inline istream &ignore_blanks_until_eol(istream &is){
int ch;
while(isspace(ch=is.get()) && ch!='\n')
; // Não faz nada, só repete a leitura enquanto for branco.
if(ch!=EOF && ch!='\n')
is.unget(ch); // Devolve dado para buffer, para próxima leitura.
return is;
}
2) Ler todos os dados com
getline(), jogando-s para um buffer de texto, para garantir que
'\n' seria sempre consumido. Quando se quiser extrair dados numéricos, pode-se usar
std::istringstream ou a função
std::stoi() do C++11.
// Usando istringstream (C++98)
#include <sstream>
/* ... */
string line;
int number;
istringstream extractor;
getline(cin line);
extractor.str(line);
if(!(extractor >> number)){
/* Falha na conversão. Toma alguma providência. */
}
// Usando std::stoi() (C++11)
string line;
int number;
size_t bad_char;
getline(cin, line);
number=stoi(line, &bad_char, 10);
if(bad_char<line.length()){
/* Dado mal-formatado. Trata o erro. */
}