我正在尝试使用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()不能像交换机外的那样工作...案例结构?
任何建议都将不胜感激。
答案 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
个对象上设置任何错误状态)。因此,更容易修复错误的用户输入。