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?

limão
fonte
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));
Pete
fonte
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.

Raças de leveza em órbita
fonte
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);
dev gr
fonte
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>
Gautham Vinod
fonte
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.

Cody
fonte
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
}
abe312
fonte
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.

Rohan Bari
fonte