2012-04-07 3 views
0

Я пытаюсь получить имя игры, которую пользователи выбирают и хранят в векторе. Я использую getline, чтобы пользователь мог использовать пробел. Когда я пытаюсь ввести новую игру, чтобы добавить ее, я не позволю. Он автоматически отображает мне библиотеку игр. Пожалуйста, скажите мне, что я делаю неправильно. Проблема в если (действие == "добавить")getline не позволит мне печатать, C++

Вот мой код:

#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

Вам не нужен cin >> newGame, потому что getline (cin, newGame); делает то, что вам нужно. – dexametason

+1

Почему вы используете оба ** cin ** и ** getline **? – sarwar026

+0

@dexametason nope, когда я использую getline, он не позволит мне вводить новую игру, чтобы добавить – Stijn

ответ

1

Я не понимаю, что ты точно написал, но:

  • getline будет получать вся строка в своем втором параметре в вашем случае newGame
  • , когда вы позвоните cin >> newGame; над линией getline, вы используете istream operator >> из string. Он читается до первого разделителя. В вашем случае это пробел между Tomb и Raider
  • Послесловие вы переписываете значение, считанное с cin >> newGame;, используя getline. До getline значение было Tomb, послесловие становится Raider

Просто удалите cin:

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

->

getline (cin, newGame); 

EDIT Теперь, когда вы вывесили весь код I я уверен, что ваш случай - именно то, о чем я думал. В строке cin >> action; вы предлагаете пользователю выбрать действие. Он вводит его и попадает в него, чтобы он мог снова активировать вашу программу. Тем не менее, cin >> будет считывать значение, но не очищать ввод нажатого пользователем. Таким образом, первый getline, который вы вызываете, просто прочитает этот ввод и ничего больше. Если вы делаете:

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

->

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

Это будет работать. Я попробовал. В основном первый cin.get(); очищает ввод, а getline запрашивает пользователя для ввода.

EDIT2 Добавляем еще одно усовершенствование при работе с новыми новыми линиями. Это, возможно, самый правильный способ справиться с ними, но я намеренно не предусматривает это решение, стараясь не перепутать OP со сложным кодом:

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

Я сделал это раньше, но проблема в том, что программа не позволяет мне что-то вводить. Whit, что я имею в виду, когда он говорит: «Назовите название игры, которую вы хотите добавить», это не позволит мне ввести что-то, и она автоматически отображает все мои игры. – Stijn

+0

Странно. Я должен проверить это. Единственная причина, по которой он не позволит вам вводить что-либо, заключается в том, что вы не очистили новую строку от предыдущего считываемого значения (скажем целое число). Дублируйте 'getline', и это должно быть исправлено (первый очистит новый символ строки). –

+0

Надену весь код, может быть, моя ошибка находится где-то в другом месте – Stijn

0

Не могли бы вы попробовать это:

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

вместо вашего данного кода:

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

Я не уверен, работает оно или нет. но, пожалуйста, попробуйте.

+0

Я попробовал, но я не помог, thx для ответ в любом случае – Stijn

+0

Это не помогает, потому что вывод ('<<') не имеет ничего общего с вводом ('>>') с точки зрения проблемы OP. – Attila

+0

да, я это понимаю. Благодарю. – sarwar026

0

Проблема может быть из-за бродячих '\ n'. getline, поскольку название предполагает получение значений полной строки. Итак, как ваш компилятор знает, когда закончите. Он использует символ \n. Если он читает левый над \n, он предположит, что линия закончилась, поэтому, если вы удалите ее, я думаю, что она должна работать. Так что просто найдите строку перед getline, которая, возможно, оставила бродячие \ n.

1

Смешивание

cin >> value1; 

и

getline(cin, value2); 

приглашает неприятности. Проблема в том, что getline читает до следующего «\ n» (и потребляет его), а >> читает до следующего пробела (и не потребляет).

Это означает, что, когда вы читаете value1 через >>, то символ новой строки остается в потоке, то вы пытаетесь прочитать целую линию и не читал «ничего» (The getline будет потреблять символ новой строки, который является непосредственный ввод потока).

Предложения удвоения getline будет работать, но только до тех пор, пока считаны через getline в другой ветке, когда он сломается, потому что getline потребляет новую строку, в отличие от >>, который не делает.

Я предлагаю вам обрабатывать все ваши данные через getline, а затем токенизировать прочитанную строку, если требуется дополнительная обработка. Таким образом, убедитесь, что обработка новой строки согласована, а также что пробелы читаются правильно.

Смежные вопросы