std :: getline não funciona dentro de um loop for
Pergunta
Eu estou tentando de entrada do usuário a cobrar em uma variável string que aceita espaços em branco para um determinado período de tempo.
Uma vez que o cin >> str
habitual não aceitar espaços em branco, então eu iria com std :: getline de
Aqui está o meu código:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local); // This simply does not work. Just skipped without a reason.
//............................
}
//............................
return 0;
}
Qualquer idéia?
Solução
Você pode ver por que isso está a falhar se você saída o que você armazenados em local
(que é um nome de variável pobres, pela maneira: P):
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
Você verá que imprime uma nova linha depois >
imediatamente depois de introduzir o seu número. Ele então se move para introduzir o resto.
Isto porque getline
está lhe dando a linha vazia que sobraram de introduzir o seu número. (Ele lê o número, mas aparentemente não remove o \n
, assim que você é deixado com uma linha em branco.) Você precisa se livrar de qualquer espaço em branco restante em primeiro lugar:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
cin >> ws; // stream out any whitespace
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
Este obras como esperado.
Off topic, talvez fosse apenas para o trecho em questão, mas o código tende a ser mais legível se você não tem using namespace std;
. Ele derrota o propósito de namespaces. Eu suspeito que era apenas para postar aqui, no entanto.
Outras dicas
Declare um personagem para entrar no carro retorno depois de ter digitado o number.char ws;int n;cin>>n;ws=cin.get();
Isto irá resolver o problema.
Usando
cin>>ws
vez dews=cin.get()
, fará primeiro caractere da seqüência para aws
variável, em vez de apenas'\n'
clareira.
Você está pressionando enter? Se não conseguir linha irá retornar nada, como ele está aguardando o fim da linha ...
Meu palpite é que você não está lendo n
corretamente, por isso é converter como zero. Desde 0 não é menor que 0, o loop nunca executa.
Eu gostaria de acrescentar um pouco de instrumentação:
int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
- O n inicializado corretamente a partir da entrada?
- Você não parecem estar a fazer qualquer coisa com getline. É isso que você quer?
- getline retorna uma referência de istream. Será que o fato de que você está largando-o sobre o assunto chão?
Em que compilador se você tentar fazer isso? Tentei em VC2008 e funcionou bem. Se eu compilei o mesmo código no g ++ (GCC) 3.4.2. Não funcionou corretamente. Abaixo está as versões trabalharam em ambos os compiladores. I dont't tem a última g ++ compilador no meu ambiente.
int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2.
for (int i = 0; i < n; i++)
{
getline(cin, local);
cout << local;
}
A questão importante é "o que você está fazendo com a corda que lhe dá a ideia de que a entrada foi ignorada?" Ou, mais precisamente, "por que você acha que a entrada foi ignorada?"
Se você está pisando através do depurador, se você compilar com otimização (que é permitido instruções Reordenar)? Eu não acho que este é o seu problema, mas é uma possibilidade.
Eu acho que é mais provável que a cadeia é preenchida, mas ele não está sendo tratado corretamente. Por exemplo, se você quer passar a entrada para funções antigos C (por ex., atoi()
), você vai precisar para extrair a seqüência estilo C (local.c_str()
).
Você pode usar diretamente a função getline na string usando delimitador da seguinte forma:
#include <iostream>
using namespace std;
int main()
{
string str;
getline(cin,str,'#');
getline(cin,str,'#');
}
Você pode str entrada tantas vezes quanto quiser, mas uma condição se aplica aqui é que você precisa para passar '#' (3º argumento) como corda delimitador ou seja, vai aceitar a entrada até '#' foi pressionado, independentemente do caractere de nova linha.