getline()不等待切换内的输入... case(C ++)

时间:2013-10-20 00:29:24

标签: c++

我正在尝试使用getline()从用户那里获得输入。

以下代码正常。它等待用户键入文件名并将其存储在fileName中。

#include <iostream>
#include <string>

using namespace std;

string inputFile();

int main() 
{
    string fileName;
    cout << "Enter the name of the file including the path" << endl;            
    getline(cin, fileName);

    return 0;
}

但是,此代码不能正常工作。

#include <iostream>
#include <string>

using namespace std;

string inputFile();

int main() 
{
    int option;

    cout << "Enter option number" << endl;
    cin >> option;

    switch (option)
    {
        case 1:
        {
            string fileName;
            cout << "Enter the name of the file including the path" << endl;            
            getline(cin, fileName);
            break;
        }
        case 2:
            cout << "You chose option 2";
            break;
        case 3:
            cout << "You chose option 3";
            break;
        default:
            cout << "value unknown";
    }   

    return 0;
}

用户输入1并且程序进入switch ... case后,再次询问用户文件名。但是,这次程序不等待响应。

为什么getline()不能像交换机外的那样工作...案例结构?

任何建议都将不胜感激。

4 个答案:

答案 0 :(得分:1)

cin在换流中留下换行符(\n)。 cin.ignore()提取并丢弃字符。它可用于刷新cin,直到达到\n

因此,解决方案是在第二次调用std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');之前添加getline(cin, fileName); 同时添加cin.clear()以删除cin

上的错误标记

示例:

case 1:
    {
        std::string fileName;
        std::cout << "Enter the name of the file including the path" << std::endl; 
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        getline(std::cin, fileName);
        break;
    }

答案 1 :(得分:0)

问题可能是,您正在通过&gt;&gt;读取案件编号。进入整数变量。通过这样做,enter键产生的换行仍然在缓冲区中。现在,getline尝试从输入流中读取并立即收到换行符。 因为它只读取下一个换行符,所以它会退出。

答案 2 :(得分:0)

问题与switch声明无关!相反,它与混合格式化输入(使用operator>>())和未格式化输入(在本例中为std::getline())有关:格式化输入在字符与格式不匹配时立即停止读取。读取整数时,只要找到非数字,它就会停止。也就是说,在号码之后输入的任何换行都将停留在流中,而std::getline()将很乐意将此新行作为停止其输入的机会。

在格式化和未格式化输入之间切换时,通常需要摆脱空格。例如,您可以使用

if (std::getline(std::cin >> std::ws, fileName)) { ... }

首先跳过任何空格,然后尝试读取fileName,如果成功,则处理输入(输入总是需要检查是否成功)。

答案 3 :(得分:0)

您在单个流上混合格式化输入和线路输入。这是一个坏主意,在同一个流上使用格式化输入operator>>或行输入std::getline()

这基本上是因为白色空间的处理方式。在这种情况下,当您阅读选项时,您将在输入上留下\n字符。

cin >> option;

这将读取选项,但在输入流(包括\n字符)上的选项(整数之后)之后留下任何内容。因此,下一次使用std :: getline()只会读取\n字符(可能会给你零字符)。

交互式用户输入是基于行的 特别是因为std::cin流被缓冲(因此在你点击返回之前不会刷新)。

因此,当我从交互式用户那里读取输入时,我总是一次读取一行文本。然后解析这一行我正在寻找的东西。

 std::string  optionLine;
 std::getline(std::cin, optionLine);

 int option = boost::lexical_cast<int>(optionLine);

注意:您不需要boost::lexical_cast,您可以与std::stringstream和另一个变量实现相同的效果。

 // A simple alternative to boost::lexical_cast
 // Not quite as pedantic as above but you can add more tests as required.
 std::stringstream optionLineStream(optionLine);
 int option;
 if (optionLineStream >> option)
 {
     // reading the option worked.
 }

一次读取一行然后解析输入也具有以下优点:您永远不会将输入置于错误状态并需要重置它(在中间std::stringstream个对象上设置任何错误状态)。因此,更容易修复错误的用户输入。