【问题标题】:cin and getline skipping input [duplicate]cin和getline跳过输入[重复]
【发布时间】:2016-02-05 22:57:58
【问题描述】:

之前我发布了一个关于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;
}

但我仍然得到同样的东西,跳过输入,当它接受输入时,它接受它们并在名称中存储空任何内容,并且在地址中它接受我在名称中写的内容,但从第二个字母到结束

我的代码有什么问题?

我尝试了cin.ignore()cin.get()cin.clear(),它们都一起单独使用,它们都不起作用

编辑:

main.cpp 中的 main 方法仅调用 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;
}

【问题讨论】:

  • 请展示一个完整的可编译示例。如果这很困难,请至少显示调用此函数的函数。
  • 好的,我将编辑问题以包含类似于堆栈跟踪的内容和示例的屏幕截图
  • 您说您尝试过 cin.ignore。给出代码,它应该可以工作。

标签: c++ input getline cin


【解决方案1】:

我遇到了这个问题,并使用 getchar() 捕获 ('\n') 新字符解决了这个问题

【讨论】:

    【解决方案2】:

    如果您在cin &gt;&gt; something 之后使用getline,则需要将换行符从中间的缓冲区中清除。

    如果不需要换行符之后的字符,我个人最喜欢的是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() 没有被定义为这样做,尽管它在某些情况下可能会起作用。它对我不起作用。
    • @aizen92,任何时候你cin &gt;&gt; something,它都会在缓冲区中留下一个换行符。只要您仍在使用cin,切换功能时缓冲区就会保留。如果与cin 相关的下一个操作是getline,它将读取剩余的换行符并似乎跳过获取输入。
    • 给你。 n3242,最后的 C++11 草案,§27.9.1.5/19 -- "int sync() 效果:如果存在放置区域,则调用 filebuf::overflow 将字符写入文件。如果获取区域存在,效果由实现定义。”
    • 如果用户一行输入超过80个字符怎么办?首选:std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), '\n');
    • 谢谢,已经为此苦苦挣扎了一段时间。
    【解决方案3】:

    你的菜单代码的结构是问题:

    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.
    

    【讨论】:

    • 这对我很有效。
    【解决方案4】:

    这里,cin 留下的'\n' 正在制造问题。

    do {
        system("cls");
        manageCustomerMenu();
        cin >> choice;               #This cin is leaving a trailing \n
        system("cls");
    
        switch (choice) {
            case '1':
                createNewCustomer();
                break;
    

    \n 正在被 createNewCustomer() 中的下一个 getline 消耗。您应该改用 getline -

    do {
        system("cls");
        manageCustomerMenu();
        getline(cin, choice)               
        system("cls");
    
        switch (choice) {
            case '1':
                createNewCustomer();
                break;
    

    我认为这会解决问题。

    【讨论】:

    • 要使用getline,您需要将choice 更改为字符串,然后不能像在switch 中那样使用它:您可以使用choice[0],但这会隐藏错误(例如,“11”将被视为 1,但对于忽略该行其余部分的已接受错误也是如此。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2014-04-01
    • 2018-09-18
    • 1970-01-01
    • 2021-11-26
    相关资源
    最近更新 更多