webentwicklung-frage-antwort-db.com.de

Getline (cin, s) nach cin verwenden

Ich brauche das folgende Programm, um die gesamte Zeile der Benutzereingabe in String-Namen zu übernehmen:

cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;

getline(cin, names);

Mit dem cin >> number-Befehl vor dem getline()-Befehl (was ich denke, ist das Problem) kann ich keine Namen eingeben. Warum?

Ich habe etwas von einem cin.clear()-Befehl gehört, aber ich habe keine Ahnung, wie das funktioniert oder warum dies überhaupt notwendig ist.

34
pauliwago
cout << "Enter the number: ";
int number;
if (cin >> number)
{
    // throw away the rest of the line 
    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }
    cout << "Enter names: ";
    string name;
    // keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
    while (getline(cin, name))
        ...use name...
}
else
{
    std::cerr << "ERROR reading number\n";
    exit(EXIT_FAILURE);
}

Im obigen Code ist dieses Bit ...

    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }

... prüft den Rest der Eingabezeile, nachdem die Nummer nur Leerzeichen enthält.

Warum nicht einfach ignorieren?

Das ist ziemlich wortreich, also ist die Verwendung von ignore im Stream nach >> x eine häufig empfohlene Alternative zum Verwerfen von Inhalten bis zum nächsten Zeilenumbruch, es besteht jedoch die Gefahr, dass Inhalte mit Ausnahme von Leerzeichen weggeworfen werden und dabei beschädigte Daten in der Datei übersehen werden. Je nachdem, ob der Inhalt der Datei vertrauenswürdig ist, wie wichtig es ist, die Verarbeitung beschädigter Daten usw. zu vermeiden, ist es Ihnen möglicherweise egal. 

Wann würden Sie also klar und ignorieren?

Daher ist std::cin.clear() (und std::cin.igore()) nicht notwendig, aber nützlich, um den Fehlerstatus zu entfernen. Zum Beispiel, wenn Sie dem Benutzer viele Möglichkeiten geben möchten, eine gültige Nummer einzugeben. 

int x;
while (std::cout << "Enter a number: " &&
       !(std::cin >> x))
{
    if (std::cin.eof())
    {
        std::cerr << "ERROR unexpected EOF\n";
        exit(EXIT_FAILURE);
    }

    std::cin.clear();  // clear bad/fail/eof flags

    // have to ignore non-numeric character that caused cin >> x to
    // fail or there's no chance of it working next time; for "cin" it's
    // common to remove the entire suspect line and re-Prompt the user for
    // input.
    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}

Kann es mit skipws oder ähnlichem nicht einfacher sein?

Eine weitere einfache, aber halbwegs gebackene Alternative zu ignore für Ihre ursprüngliche Anforderung ist die Verwendung von std::skipws, um Leerzeichen vor dem Lesen von Zeilen zu überspringen.

if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...

... aber wenn es Eingaben wie "1E6" erhält (z. B. ein Wissenschaftler, der versucht, 1.000.000 einzugeben, C++ jedoch nur diese Notation für Fließkommazahlen unterstützt), akzeptiert dies nicht, würden Sie number auf 1 und E6 setzen. als erster Wert von name gelesen. Wenn Sie eine gültige Nummer gefolgt von einer oder mehreren leeren Zeilen hätten, würden diese Zeilen separat ignoriert.

9
Tony Delroy
cout << "Enter the number: ";
int number;
cin >> number;

cin.ignore(256, '\n'); // remaining input characters up to the next newline character
                       // are ignored

cout << "Enter names: ";
string names;
getline(cin, names);
16

Eine andere Möglichkeit, dies zu tun, besteht darin, eine 

cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 

nach Ihrem cin>>number;, um den Eingabepuffer vollständig zu leeren (alle zusätzlichen Zeichen werden zurückgewiesen, bis eine neue Zeile gefunden wird). Sie müssen #include <limits>, um die max()-Methode zu erhalten.

15
jonsca

Versuchen:

int number;

cin >> number;

char firstCharacterOfNames;
cin >> firstCharacterOfNames;  // This will discard all leading white space.
                               // including new-line if there happen to be any.

cin.unget();                   // Put back the first character of the name.

std::string  names;
std::getline(cin, names);      // Read the names;

Alternative. Wenn Sie wissen, dass Nummer und Namen immer auf unterschiedlichen Zeilen stehen.

cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
std::getline(cin, names);
9
Martin York

Sie können std :: ws verwenden, um alle Leerzeichen im Eingabepuffer zu extrahieren, bevor Sie getline verwenden. Header für std :: ws ist sstream.

cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
5
Rajeev Atmakuri
cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names

es ist ziemlich selbsterklärend, es gibt ein\n im Stream, das cin >> number verwendet, das Namen zugewiesen wird, wenn es zum ersten Mal verwendet wird. Durch die Wiederverwendung der Getline wird jetzt der korrekte Wert geschrieben.

1

Oder Sie können den Eingabepuffer leeren, um die Zeichenfolge zu lesen

fflush (stdin)

es ist in header stdio.h definiert.

Dieser Code funktioniert ..

cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
fflush(stdin);  //FLUSHING STDIN
getline(cin, names);
1
pz64_

Sie finden die gewünschte Antwort in cppreference .

Bei Verwendung unmittelbar nach einer durch Leerzeichen getrennten Eingabe, z. Nach int n; std::cin >> n; verbraucht getline das durch den Operator >> im Eingabestream verbleibende Endzeilenzeichen und kehrt sofort zurück. Eine gebräuchliche Lösung besteht darin, alle verbleibenden Zeichen in der Eingabezeile mit cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); zu ignorieren, bevor Sie zur zeilenorientierten Eingabe wechseln.

0
shuaihanhungry
cout << "Enter the number: ";

int number;
cin >> number;

getc(stdin);  //you need add this line 

cout << "Enter names: ";

string names;

getline(cin, names);
0
H R shuvo

Konzeptionell denke ich, Sie möchten, dass jede Antwort genau eine Zeile ist. Warum probierst du das nicht?

cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);

cout << "Enter names: ";
string names;
getline(cin, names);

Der Code verbraucht das erste Newline-Zeichen korrekt, gibt die Nummer an, wenn die Zeile korrekt ist, oder löst eine Ausnahme aus, wenn dies nicht der Fall ist. Alles kostenlos!

0
ngọcminh.oss

sie möchten cin.ignore () nach Ihren cin-Anweisungen verwenden, da Sie das\"\" im Puffer ignorieren möchten, nachdem Sie Ihre int -Variable mit cin genommen haben.

ich habe ein ähnliches Programm, das ich mit einem ähnlichen Problem verwendet habe:

#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main() {
    int i = 4;
    double d = 4.0;
    string s = "HackerRank ";

    // Declare second integer, double, and String variables.
    int n;
    double d2;
    string str;

    // Read and save an integer, double, and String to your variables.
    cin >> n;
    cin >> d2;

    cin.ignore();

    getline(cin, str);

    // Print the sum of both integer variables on a new line.
    cout << i + n << endl;


    // Print the sum of the double variables on a new line.
    cout << d + d2 << endl;

    // Concatenate and print the String variables on a new line
    cout << s << str << endl;

    // The 's' variable above should be printed first.

    return 0;
}
0
lopezdp

ich habe gerade gebraucht 

getline(cin >> ws,lard.i_npute);

mit dem Standard

#include <iostream>

header in den Fällen, in denen ich Probleme mit Wagenrückläufen hatte und der WS-Manipulator funktionierte. Ich werde wahrscheinlich anfangen, Schleifenfunktionen als Klassen einzubetten und Konstruktor- und Destruktoraufrufe mindestens zu verwenden.

0
1911 Soldier

Versuchen Sie es mit cin.ignore (), wenn Sie die Funktion cin vor der getline () - Funktion verwenden

void inputstu(){
    cout << "Enter roll Number:";
    cin >> roll_no;
    cin.ignore(); //ignore the withspace and enter key
    cout << "Enter name:";
    getline(cin, stu_name);
}
0
Vishal Rai