std :: cin input con spazi?


144
#include <string>

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

L'utente desidera inserire "Hello World". Ma cinnon riesce nello spazio tra le due parole. Come posso cinprendere in tuttoHello World ?

In realtà lo sto facendo con le strutture e cin.getlinenon sembra funzionare. Ecco il mio codice:

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

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

Questo produce un errore. Qualche idea?


27
Non dovresti modificare le tue domande per porre nuove domande del genere. Il motivo è che le persone hanno già dato le risposte alla tua domanda originale e ora quelle risposte sembrano fuori contesto. Se la tua domanda originale è già stata risolta, basta iniziare una nuova domanda per evitare confusione.
Pete,

È evidente dopo un piccolo esame, ma potresti aggiungere una dichiarazione per la variabile in librarymodo che sia chiaro che è del tipocd
chandsie

scusate ragazzi, questo è stato fatto in fretta, ripubblicerò questo.
limone

1
Se hai intenzione di ripubblicarlo a titolo di sostituzione, contrassegna la domanda per l'eliminazione da una mod.
Razze di leggerezza in orbita

2
Nel suo aggiornamento, si sta cercando di getlinein una int. Certo che fallisce.
Ben Voigt

Risposte:


102

Devi usare cin.getline() :

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

7
@Kevin Meh, succede. Il C ++ non è esattamente così intuitivo come vorremmo che fosse.
Pete,

61
Ew; perché usare char-buffers? È il 2011.
Razze di leggerezza in orbita

3
E perché non usarlo cin.getline(input, sizeof(input));? Inoltre, non dovresti controllare lo stato del reso?
Jonathan Leffler,

2
@JonathanLeffler Al momento in cui è stato scritto, questa era la risposta che avevo per la domanda che era stata originariamente posta (guarda il primo commento per la domanda reale e vedrai che il contesto era cambiato a causa di una modifica da parte dell'OP). Ad ogni modo, se ritieni che la risposta sia così terribile, ridimensionala. Riconosco che questa potrebbe non essere la soluzione "migliore" ma è una soluzione non meno. Invece di chiedermi perché non ho usato qualcosa, potresti dirci perché dovremmo farlo a modo tuo.
Pete,

7
La tua risposta non è terribile e non necessita di downgrade. Penso che due piccoli cambiamenti lo migliorerebbero. La modifica 1 userebbe sizeof(input)al posto di 100 nella chiamata a cin.getline(); ciò significherebbe che è possibile modificare la dimensione del buffer di input e che è necessario modificare solo una riga anziché due righe. La modifica 2 consisterebbe nel testare il ritorno cin.getline()utilizzando, ad esempio, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }o qualcosa di simile, per ricordare all'OP che le operazioni di input, in particolare, sono vulnerabili a comportamenti imprevisti. Anche altre risposte hanno bisogno di questo.
Jonathan Leffler,

215

Non "fallisce"; smette di leggere. Vede un token lessicale come una "stringa".

Utilizzare 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;
}

Si noti che questo non è lo stesso di std::istream::getline, che funziona con i charbuffer in stile C anziché con std::strings.

Aggiornare

La tua domanda modificata assomiglia poco all'originale.

Stavi cercando di getlineinserire un intbuffer, non una stringa o un carattere. Le operazioni di formattazione dei flussi funzionano solo con operator<<e operator>>. O usane uno (e modifica di conseguenza per l'inserimento di più parole), oppure usa getlinee converti lessicamente in intafter-the-fact.


2
Mi piace questa risposta molto meglio di quella accettata, perché non ho bisogno di specificare una lunghezza di carattere.
TheWanderer

1
@TheWanderer In effetti, questo è un vantaggio significativo.
Razze di leggerezza in orbita

Ricorda di includere sstream: #include <sstream>
GilbertS

@LightnessRacesinOrbit, puoi aiutarmi, per favore? Questo mi dà una nuova riga in più senza motivo durante la stampa del mio output.
Anshuman Kumar il

@AnshumanKumar Penso che getlinepossa includere la nuova riga finale nella stringa che restituisce. In tal caso, spetta a te eliminarlo.
Mark Ransom,

31

La libreria standard fornisce una funzione di input chiamata ws, che consuma spazio bianco da un flusso di input. Puoi usarlo in questo modo:

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

4
Penso che questa sia la risposta migliore finora. Posso combinare questo con lo std :: cin >> sopra.
Andra,

1
La migliore risposta finora. Quando lo uso std::getline(std::cin, s)diventerei molto confuso e direi, input interrotto durante l'attesa di input in un while/ forloop. Questa opzione ha risolto il mio problema!
Omerowitz

Includi sstream: #include <sstream>
GilbertS

24

Uso :

getline(cin, input);

la funzione è disponibile in

#include <string>

2
+1 Questa è l'unica risposta che ha funzionato per me. Il resto delle risposte dice di usare cin.getline () ma questo mi ha dato solo un errore dicendo che la funzione non esiste.
Blembo,

7
@blembo: Davvero? Perché la mia risposta, pubblicata più di tre anni prima di questa, dice esattamente la stessa cosa (al contrario di ciò che affermi che dice).
Corse di leggerezza in orbita il

@blembo: E se cin.getlinenon esiste sul tuo sistema, hai fatto qualcosa di molto sbagliato. Molto probabilmente stavi passando argomenti sbagliati. Meglio non incolpare gli altri per i tuoi errori ...
Razze di leggerezza in orbita

13

Si desidera utilizzare la funzione .getline in 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;
}

Ho preso l'esempio da qui . Dai un'occhiata per maggiori informazioni ed esempi.


12
In effetti, raramente vuoi usare member- getline. È obsoleto. Usa getlineinvece gratuitamente , che può essere utilizzato con std::string. [A proposito, cplusplus.com non è una risorsa consigliata]
Razze di leggerezza in orbita

1
@Tomalak Perché cplusplus.com non è raccomandato? Lo uso sempre: P
limone

6
@KevinDuke: i tutorial possono essere fuorvianti e inaccurati e il riferimento contiene una moltitudine di errori. Queste sono buone risorse.
Corse di leggerezza in orbita

1
@NickSweeting: Sì; usa questo invece.
Razze di leggerezza in orbita

1
Per i collegamenti di documentazione, cppreference.com è un sostituto efficace di cplusplus.com (entrambi sono parafrasi non ufficiali)
Ben Voigt,

4

IL MODO C

È possibile utilizzare la getsfunzione presente in cstdio (stdio.h in c):

#include<cstdio>
int main(){

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

IL MODO C ++

gets viene rimosso in c ++ 11.

[Consigliato]: è possibile utilizzare getline (cin, name) che è in string.h o cin.getline (name, 256) che è in iostreamsé.

#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
Pessimo consiglio, getsimpossibile da usare in sicurezza. È stato persino rimosso completamente in C11.
Mat

1

Preferisco usare il seguente metodo per ottenere l'input:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

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

    return 0;
}

In realtà è super facile da usare piuttosto che definire la lunghezza totale dell'array per una stringa che contiene un carattere spazio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.