2012-04-07 14 views
0

Ich versuche, den Namen eines Spiels die Benutzer wählen und speichern Sie es in einem Vektor. Ich benutze getline, so dass der Benutzer ein Leerzeichen verwenden kann. Wenn ich versuche ein neues Spiel einzugeben, wird es mich nicht lassen. Es zeigt automatisch mir Spiele-Bibliothek. Bitte sagen Sie mir, was ich falsch mache. Problem ist bei if (Aktion == "add")getline lässt mich nicht tippen, C++

Hier mein Code ist:

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 

int main() 
{ 
    vector<string>::const_iterator myIterator; 
vector<string>::const_iterator iter;     

vector<string> games;         
games.push_back("Crysis 2"); 
games.push_back("GodOfWar 3"); 
games.push_back("FIFA 12"); 

cout <<"Welcome to your Games Library.\n"; 
cout <<"\nThese are your games:\n"; 
for (iter = games.begin(); iter != games.end(); ++iter) 
{ 
    cout <<*iter <<endl; 
} 
//the loop! 
string action; 
string newGame; 

cout <<"\n-Type 'exit' if you want to quit.\n-Type 'add' if you want to add a game.\n-Type 'delete' if you want to delete a game.\n-Type 'find' if you want to search a game.\n-Type 'game' if you don't know what game to play.\n-Type 'show' if you want to view your library."; 

while (action != "exit") 
{ 


    cout <<"\n\nWhat do you want to do: "; 
    cin >> action; 

       //problem is here 
    if (action == "add") 
    { 
     cout <<"\nType the name of the game you want to add: "; 
     getline (cin, newGame); 

     games.push_back(newGame); 

     for (iter = games.begin(); iter != games.end(); ++iter) 
     { 
      cout <<*iter <<endl; 
     } 

     continue; 
    } 
    else if (action == "show") 
    { 
     cout <<"\nThese are your games:\n"; 
     for (iter = games.begin(); iter != games.end(); ++iter) 
     { 
      cout <<*iter <<endl; 
     } 
    } 
    else if (action == "delete") 
    { 
     cout <<"Type the name of the game you want to delete: "; 
     cin >> newGame; 
     getline (cin, newGame); 

     iter = find(games.begin(), games.end(), newGame); 

     if(iter != games.end()) 
     { 
      games.erase(iter); 
      cout <<"\nGame deleted!"; 
     } 
     else 
     { 
      cout<<"\nGame not found."; 
     } 

     continue; 
    } 
    else if (action == "find") 
    { 
     cout <<"Which game you want to look for in your library: "; 
     cin >> newGame; 
     getline (cin, newGame); 

     iter = find(games.begin(), games.end(), newGame); 

     if (iter != games.end()) 
     { 
      cout << "Game found.\n"; 
     } 
     else 
     { 
      cout << "Game not found.\n"; 
     } 

     continue; 
    } 
    else if (action == "game") 
    { 
     srand(static_cast<unsigned int>(time(0))); 
     random_shuffle(games.begin(), games.end()); 
     cout << "\nWhy don't you play " << games[0]; 

     continue; 
    } 
    else if (action == "quit") 
    { 
     cout <<"\nRemember to have fun while gaming!!\n"; 
     break; 
    } 
    else 
    { 
     cout <<"\nCommand not found"; 
    } 
} 
return 0; 

} 
+2

Sie brauchen nicht cin >> newGame, weil getline (cin, newGame); tut was du brauchst. – dexametason

+1

Warum verwenden Sie sowohl ** cin ** als auch ** getline **? – sarwar026

+0

@dexametason nein, wenn ich getline benutze es wird nicht lassen Sie mich ein neues Spiel eingeben, um hinzuzufügen – Stijn

Antwort

1

ich nicht bekommen, was Sie genau geschrieben, aber:

  • getline wird holen die ganze Zeile in ihrem zweiten Parameter in Ihrem Fall newGame
  • Wenn Sie cin >> newGame; über die getline aufrufen, verwenden Sie zuerst die istream operator >> von string. Es liest bis zum ersten Trennzeichen. Diese in Ihrem Fall ist der Raum zwischen Tomb und Raider
  • Afterwords Sie den Wert mit cin >> newGame; mit dem getline lesen überschrieben. Bis zum getline war der Wert Tomb, anschliessend es Raider

Entfernen Sie einfach die cin wird:

cin >> newGame; 
getline (cin, newGame); 

->

getline (cin, newGame); 

EDIT Nun, wie Sie alle geschrieben Code I Ich bin sicher, dass dein Fall genau das ist, woran ich gedacht habe. In der Zeile cin >> action; fordern Sie den Benutzer auf, eine Aktion auszuwählen. Er geht hinein und drückt Enter, damit er Ihr Programm wieder aktivieren kann. Die cin >> wird jedoch den Wert lesen, aber nicht die Eingabe löschen, die der Benutzer gedrückt hat. Daher wird die erste getline, die Sie aufrufen, nur diese Eingabe und sonst nichts lesen. Wenn Sie das tun:

cin >> newGame; 
getline (cin, newGame); 

->

cin.get(); 
getline (cin, newGame); 

Dies funktioniert. Ich versuchte es. Im Wesentlichen die erste cin.get(); löscht die Eingabe und die getline fordert den Benutzer zur Eingabe auf.

EDIT2 Hinzufügen einer weiteren Verbesserung auf der Lay die folgenden neuen Zeilen behandelt werden. Dies ist vielleicht der richtige Weg, um sie zu handhaben, aber ich habe absichtlich diese Lösung nicht bieten die OP mit komplexen Code nicht zu verwirren versuchen:

if (cin.peek() == '\n' || cin.peek() == '\r') { 
     cin.get(); 
    } 
    getline (cin, newGame); 
+0

Ich habe das vorher gemacht, aber das Problem ist, dass das Programm mich nicht etwas eingibt. Damit meine ich, wenn es heißt: "Gib den Namen des Spiels ein, das du hinzufügen willst", lasse ich mir nicht die Chance geben, etwas einzugeben, und es zeigt automatisch alle meine Spiele an. – Stijn

+0

Seltsam. Das sollte ich testen. Der einzige Grund, warum Sie nichts eingeben können, ist, dass Sie den Zeilenumbruch nicht vom vorherigen Wert gelesen haben (sagen wir eine Ganzzahl). Dupliziere die "getline" und das sollte behoben werden (die erste wird das neue Liniensymbol löschen). –

+0

Ich werde den ganzen Code aufsetzen, vielleicht ist mein Fehler woanders. – Stijn

0

Könnten Sie bitte diese versuchen:

cout <<"Type the name of the game you want to add: "; 

statt von Ihrem dieser Code:

cout <<"\nType the name of the game you want to add: "; 

Ich bin mir nicht sicher, ob es funktioniert oder nicht. aber bitte probier es.

+0

Ich habe es versucht, aber ich habe nicht geholfen, thx für die Antwort auf jeden Fall – Stijn

+0

Es hilft nicht, weil die Ausgabe ('<<') vom Standpunkt des OP-Problems nichts mit der Eingabe ('>>') zu tun hat. – Attila

+0

ja, ich verstehe es. Vielen Dank. – sarwar026

0

Das Problem vielleicht wegen eines streunenden '\ n'. getline, wie der Name schon sagt, bekommt die Werte der kompletten Zeile. Wie weiß Ihr Compiler, wenn Sie fertig sind? Es verwendet das Zeichen \n. Wenn es ein links über \n liest, wird es annehmen, dass die Linie geendet hat, also wenn Sie es entfernen, denke ich, dass es funktionieren sollte. So finden Sie einfach die Linie vor der getline, die ein stray \ n verlassen haben kann.

1

Misch

cin >> value1; 

und

getline(cin, value2); 

lädt Schwierigkeiten. Das Problem ist, dass getline liest bis zum nächsten '\ n' (und verbraucht es), während >> bis zum nächsten Leerzeichen liest (und es nicht konsumiert).

Das bedeutet, dass, wenn Sie value1 über >> lesen, der neuen Online-Charakter in dem Strom bleibt, dann Sie versuchen, eine ganze Zeile zu lesen und „nichts“ (die getline verbrauchen das neuen Online-Zeichen, das die gelesene sofortige Eingabe aus dem Stream).

Anregungen des getline verdoppeln wird funktionieren, aber nur, bis Sie über getline in einem anderen Zweig zu lesen, wenn es bricht, weil das getline die new-line, im Gegensatz zu >>, was nicht der Fall ist verbraucht.

Ich schlage vor, Sie behandeln alle Ihre Eingabe über getline, dann Tokenize die gelesene Zeichenfolge, wenn weitere Verarbeitung benötigt wird. Auf diese Weise stellen Sie sicher, dass die Handhabung der neuen Zeile konsistent ist und dass Leerzeichen korrekt gelesen werden.

Verwandte Themen