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.