Вопрос по c++, input – вход cin и getline [дубликаты]

41

На этот вопрос уже есть ответ:

Почему std :: getline () пропускает ввод после форматированного извлечения? 3 ответа

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

вот мой код:

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() все они вместе и одни, ни один из них не работал

РЕДАКТИРОВАТЬ

етод @main в 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;
}
Пожалуйста, покажите полный пример для компиляции. Если это сложно, по крайней мере, покажите функцию, из которой вызывается эта функция. Benjamin Lindley
ok, я отредактирую вопрос, чтобы включить что-то похожее на трассировку стека и снимок экрана примера hakuna matata
ты сказал, что попробовал cin.ignore. дай код, он должен был сработать. J-16 SDiZ

Ваш Ответ

4   ответа
76

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
sync() не определен, чтобы сделать это, хотя это может работать в некоторых случаях. Это не работает для меня. Benjamin Lindley
@ aizen92, в любое время, когда тыcin >> something, он оставит новую строку в буфере. Буфер остается при переключении функций до тех пор, пока вы все еще используетеcin. Если следующая операция связана сcin являетсяgetline, он прочтет этот оставшийся символ новой строки и пропустит ввод. chris
Спасибо, довольно долго боролся с этим. Saheb
Вот ты иди. n3242, последний черновик C ++ 11, §27.9.1.5 / 19 - "int sync () Эффекты: если область размещения существует, вызывает filebuf :: overflow для записи символов в файл. Если область получения существует, эффект определяется реализацией." Benjamin Lindley
Что если пользователь наберет более 80 символов в строке? Предпочитаю:std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); Robᵩ
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

Вот,'\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;

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

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

используя getchar (), чтобы поймать ('\ n') новый символ

Похожие вопросы