std :: cin input com espaços?


144
#include <string>

std::string input;
std::cin >> input;

O usuário deseja inserir "Hello World". Mas cinfalha no espaço entre as duas palavras. Como posso fazer o cintake no todo Hello World?

Na verdade, estou fazendo isso com estruturas e cin.getlineparece não funcionar. Aqui está o meu código:

struct cd
{
    std::string CDTitle[50];
    std::string Artist[50];
    int number_of_songs[50];
};

std::cin.getline(library.number_of_songs[libNumber], 250);

Isso gera um erro. Alguma ideia?


27
Você não deve editar suas perguntas para fazer novas perguntas como essa. O motivo é que as pessoas já deram respostas à sua pergunta original e agora essas respostas parecem fora de contexto. Se sua pergunta original já tiver sido respondida, basta iniciar uma nova pergunta para evitar confusão.
Pete

É evidente após um exame pouco, mas você poderia por favor, adicionar uma declaração para a variável libraryde modo que é claro que é do tipocd
chandsie

desculpe pessoal, isso foi feito às pressas, vou repassar isso.
lemon

1
Se você deseja repassá-lo como substituto, sinalize a pergunta para exclusão por um mod.
Lightness Races in Orbit

2
Na sua atualização, você está tentando getlineentrar em um int. Claro que falha.
Ben Voigt

Respostas:


102

Você tem que usar cin.getline():

char input[100];
cin.getline(input,sizeof(input));

7
@ Kevin Meh, isso acontece. C ++ não é exatamente tão intuitivo quanto gostaríamos que fosse.
Preço

61
Ai credo; por que usar char-buffers? É 2011.
Lightness Races in Orbit

3
E por que não usar cin.getline(input, sizeof(input));? Além disso, você não deve verificar o status de retorno?
Jonathan Leffler

2
@ JonathanLeffler No momento em que isso foi escrito, essa era a resposta que eu tinha para a pergunta que foi feita originalmente (observe o primeiro comentário da pergunta real e você verá que o contexto mudou devido a uma edição do OP). De qualquer forma, se você acha que a resposta é terrível, diminua o voto. Reconheço que essa pode não ser a melhor solução, mas não menos importante. Em vez de perguntar por que não usei algo, você poderia nos dizer por que devemos fazer do seu jeito.
Pete

7
Sua resposta não é terrível e não precisa de voto negativo. Eu acho que duas pequenas mudanças o melhorariam. A alteração 1 usaria sizeof(input)no lugar de 100 na chamada para cin.getline(); isso significa que você pode alterar o tamanho do buffer de entrada e precisa alterar apenas uma linha em vez de duas linhas. A alteração 2 seria testar o retorno cin.getline()usando, por exemplo, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }ou algo semelhante, para lembrar ao OP que as operações de entrada, em particular, são vulneráveis ​​a comportamentos inesperados. Outras respostas também precisam disso.
Jonathan Leffler

215

Não "falha"; apenas para de ler. Ele vê um token lexical como uma "string".

Use std::getline:

int main()
{
   std::string name, title;

   std::cout << "Enter your name: ";
   std::getline(std::cin, name);

   std::cout << "Enter your favourite movie: ";
   std::getline(std::cin, title);

   std::cout << name << "'s favourite movie is " << title;
}

Observe que isso não é o mesmo que std::istream::getline, que funciona com charbuffers de estilo C em vez de std::strings.

Atualizar

Sua pergunta editada tem pouca semelhança com o original.

Você estava tentando getlineentrar em um intbuffer de seqüência de caracteres ou não. As operações de formatação de fluxos funcionam apenas com operator<<e operator>>. Use um deles (e ajuste de acordo para entrada de várias palavras) ou use getlinee converta lexicamente para intdepois do fato.


2
Gosto desta resposta muito melhor do que a aceita, porque não preciso especificar um tamanho de caractere.
TheWanderer

1
@ TheWanderer De fato, esse é um benefício significativo.
Lightness Races in Orbit

Lembre-se de incluir o sstream: #include <sstream>
GilbertS

@LightnessRacesinOrbit, você pode ajudar? Isso me dá uma nova linha extra sem motivo durante a impressão da minha saída.
Anshuman Kumar 25/06

@AnshumanKumar Acho que getlinepode incluir a nova linha final na string que ele retorna. Em caso afirmativo, cabe a você excluí-lo.
Mark Ransom

31

A Biblioteca padrão fornece uma função de entrada chamada ws, que consome espaço em branco de um fluxo de entrada. Você pode usá-lo assim:

std::string s;
std::getline(std::cin >> std::ws, s);

4
Eu acho que essa é a melhor resposta até agora. Eu posso combinar isso com o std :: cin >> acima.
Andra

1
Melhor resposta até agora. Ao usar, std::getline(std::cin, s)eu ficaria muito confuso e diria que interrompeu a entrada ao esperar por entradas em um loop while/ for. Esta opção resolveu meu problema!
omerowitz 8/01

Incluir sstream: #include <sstream>
GilbertS

24

Usar :

getline(cin, input);

a função pode ser encontrada em

#include <string>

2
+1 Esta é a única resposta que realmente funcionou para mim. O restante das respostas diz usar cin.getline (), mas isso me deu um erro dizendo que a função não existe.
blembo 9/12/2015

7
@blembo: Sério? Porque minha resposta, postada mais de três anos antes desta, diz exatamente a mesma coisa (ao contrário do que você afirma).
Lightness Races em órbita

@ blembo: E se cin.getlinenão existe no seu sistema, você fez algo muito errado. Provavelmente você estava passando os argumentos errados. Melhor para não culpar os outros por seus erros ...
Leveza raças em Orbit

13

Você deseja usar a função .getline em cin.

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

Tomou o exemplo daqui . Confira para mais informações e exemplos.


12
Na verdade, você raramente deseja usar member- getline. Está fora de moda. Em getlinevez disso, use free , que pode ser usado com std::string. [BTW, cplusplus.com não é um recurso recomendado]
Lightness Races in Orbit

1
@Tomalak Por que o cplusplus.com não é recomendado? Eu uso o tempo todo: P
lemon

6
@ KevinDuke: Os tutoriais podem ser enganosos e imprecisos, e a referência contém uma infinidade de erros. Estes são bons recursos.
Lightness Races in Orbit

1
@NickSweeting: Sim; use isso em seu lugar.
Lightness Races in Orbit

1
Para links de documentação, cppreference.com é um substituto eficaz para cplusplus.com (ambos são paráfrases não-oficiais)
Ben Voigt

4

O CAMINHO

Você pode usar a getsfunção encontrada no cstdio (stdio.h em c):

#include<cstdio>
int main(){

char name[256];
gets(name); // for input
puts(name);// for printing 
}

A MANEIRA C ++

gets é removido no c ++ 11.

[Recomendado]: você pode usar getline (cin, nome) que está dentro string.h ou cin.getline (nome, 256), que é por iostreamsi só.

#include<iostream>
#include<string>
using namespace std;
int main(){

char name1[256];
string name2;
cin.getline(name1,256); // for input
getline(cin,name2); // for input
cout<<name1<<"\n"<<name2;// for printing
}

10
Muito mau conselho, getsé impossível usar com segurança. Foi até completamente removido no C11.
Mat

1

Prefiro usar o seguinte método para obter a entrada:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

    cout << "Hello, Input your name please: ";
    getline(cin, name);

    return 0;
}

Na verdade, é super fácil de usar, em vez de definir o comprimento total da matriz para uma string que contém um caractere de espaço.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.