2012-05-11 2 views
36

ранее я поставил вопрос о cin пропуском ввода, и я получил результаты для очистки, и использовал istringstream, но теперь я пробовал все возможные решения, но никто из них не работает.cin и getline пропускают ввод

вот мой код:

void createNewCustomer() { 
    string name, address; 

    cout << "Creating a new customer..." << endl; 
    cout << "Enter the customer's name: "; getline(cin, name); 
    cout << "Enter the customer's address: "; getline(cin, address); 

    Customer c(name, address, 0); 
    CustomerDB::addCustomer(c); 

    cout << endl; 
} 

, но я все еще получаю то же самое, пропуская вход, и когда он действительно принимает входной сигнал, он принимает их и сохраняет в имени пустого ничего, и в адрес его берет то, что я написал от имени, но от 2-го письма до конца

что не так с моим кодом?

Я попробовал cin.ignore(), cin.get() и cin.clear() все их вместе и в одиночку, ни один из них не работал

EDIT:

основной метод в main.cpp вызывает mainMenu() только

void mainMenu() { 
    char choice; 

    do { 
     system("cls"); 
     mainMenuDisplay(); 
     cin >> choice; 
     system("cls"); 

     switch (choice) { 
      case '1': 
       customerMenu(); 
       break; 

      case '2': 
       dvdMenu(); 
       break; 

      case '3': 
       receiptMenu(); 
       break; 

      case '4': 
       outro(); 
       break; 

      default: 
       cout << '\a'; 
     } 

     cin.ignore(); 
     cin.get(); 
    } while (choice != '4'); 
} 

я выберу 1 для примера клиента, это customerMenu()

void customerMenu() { 
    char choice; 

    do { 
     system("cls"); 
     manageCustomerMenu(); 
     cin >> choice; 
     system("cls"); 

     switch (choice) { 
      case '1': 
       createNewCustomer(); 
       break; 

      case '2': 
       deleteCustomer(); 
       break; 

      case '3': 
       updateCustomerStatus(); 
       break; 

      case '4': 
       viewCustomersList(); 
       break; 

      case '5': 
       mainMenu(); 
       break; 

      default: 
       cout << '\a'; 
     } 

     cin.ignore(); 
     cin.get(); 
    } while (choice != '5'); 
} 

Я снова выбираю 1 для создания нового объекта клиента, который теперь перейдет к MainFunctions.cpp, который будет вызывать функцию createNewCustomer(), которая является первой.

void createNewCustomer() { 
    string name, address; 

    cout << "Creating a new customer..." << endl; 
    cout << "Enter the customer's name: "; cin.getline(name,256); 
    cout << "Enter the customer's address: "; cin.getline(address,256); 

    Customer c(name, address, 0); 
    CustomerDB::addCustomer(c); 

    cout << endl; 
} 
+2

Пожалуйста, покажите полный компилируемый пример. Если это сложно, пожалуйста, по крайней мере покажите функцию, из которой вызывается эта функция. –

+0

ОК, я отредактирую вопрос, чтобы включить то, что как-то напоминает трассировку стека, и снимок экрана примера –

+0

вы сказали, что попробовали cin.ignore. дайте код, он должен сработать. –

ответ

73

Если вы используете getline после cin >> something, вам нужно очистить строку из буфера между ними.

Мой личный фаворит для этого, если нет символов перед новой строкой, это cin.sync(). Однако это реализация определена, поэтому она может работать не так, как для меня. Для чего-то твердого, используйте cin.ignore(). Или использовать std::ws удалить ведущие пробелы, если желательно:

int a; 

cin >> a; 
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n'); 
//discard characters until newline is found 

//my method: cin.sync(); //discard unread characters 

string s; 
getline (cin, s); //newline is gone, so this executes 

//other method: getline(cin >> ws, s); //remove all leading whitespace 
+3

'sync()' не определен для этого, хотя может работать в некоторых случаях. Это не работает для меня. –

+0

@BenjaminLindley, это всегда отлично работает для меня. Можете ли вы найти документацию, в которой не требуется очищать непрочитанные символы? – chris

+0

Я не использовал cin перед getline в функции 'createNewCustomer()', но он используется в функциях, вызывающих 'createNewCustomer()' как в 'mainMenu()' и 'customerMenu()' –

2

Здесь '\n' оставленную CIN, создает проблемы.

do { 
    system("cls"); 
    manageCustomerMenu(); 
    cin >> choice;    #This cin is leaving a trailing \n 
    system("cls"); 

    switch (choice) { 
     case '1': 
      createNewCustomer(); 
      break; 

Этот \n потребляется в следующем GetLine в createNewCustomer(). Вы должны использовать getline вместо этого -

do { 
    system("cls"); 
    manageCustomerMenu(); 
    getline(cin, choice)    
    system("cls"); 

    switch (choice) { 
     case '1': 
      createNewCustomer(); 
      break; 

Я думаю, что это решит проблему.

+0

Чтобы использовать 'getline', вам нужно будет изменить' choice' на строку, тогда его нельзя использовать как в 'switch': вы можете использовать' choice [0] ', но это спрячет ошибки (например, 11 'будет рассматриваться как 1, но это также относится к принятой ошибке, которая игнорирует остальную часть строки. –

10

Структура кода меню является вопрос:

cin >> choice; // new line character is left in the stream 

switch (...) { 
    // We enter the handlers, '\n' still in the stream 
} 

cin.ignore(); // Put this right after cin >> choice, before you go on 
       // getting input with getline. 
2

я столкнулся этот вопрос, и решить эту проблему с помощью GetChar(), чтобы поймать («\ п») новый символ

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