Rad*_*cus 51 c++ ignore cin getline
我用C++编写了一个非常基本的程序,它要求用户输入一个数字,然后输入一个字符串.令我惊讶的是,在运行程序时,它永远不会停止询问字符串.它只是跳过了它.在对StackOverflow进行一些阅读后,我发现我需要添加一行说:
cin.ignore(256, '\n');
Run Code Online (Sandbox Code Playgroud)
在获取字符串输入的行之前.添加修复问题并使程序正常工作.我的问题是为什么C++需要这一cin.ignore()行,我如何预测何时需要使用cin.ignore()?
这是我写的程序:
#include <iostream>
#include <string>
using namespace std;
int main()
{
double num;
string mystr;
cout << "Please enter a number: " << "\n";
cin >> num;
cout << "Your number is: " << num << "\n";
cin.ignore(256, '\n'); // Why do I need this line?
cout << "Please enter your name: \n";
getline (cin, mystr);
cout << "So your name is " << mystr << "?\n";
cout << "Have a nice day. \n";
}
Run Code Online (Sandbox Code Playgroud)
sav*_*ays 47
忽略正如名称所暗示的那样.
它不会"丢弃"你不需要的东西,它会忽略你调用它时指定的字符数量,直到你指定为断点的字符.
它适用于输入和输出缓冲区.
从本质上讲,对于std::cin在getline调用之前使用ignore的语句,因为当用户输入内容时std::cin,它们会按Enter键并且'\n'char进入cin缓冲区.然后,如果您使用getline,它将获取换行符char而不是您想要的字符串.所以你做了一个std::cin.ignore(1000,'\n'),那应该清除缓冲区到你想要的字符串.(1000用于在指定的断点之前跳过特定数量的字符,在本例中为\n换行符.)
Him*_*rma 19
简答
为什么?因为输入流中仍有空格(回车、制表符、空格、换行符)。
什么时候?当您使用某些不独立的函数时,会忽略前导空格。Cin 默认会忽略并删除前导空格,但 getline 不会自行忽略前导空格。
现在详细解答。
您在控制台中输入的所有内容都是从标准流 stdin 中读取的。当您输入某些内容时,例如在您的情况下为 256 并按 Enter,流的内容将变为256\n. 现在 cin 获取 256 并将其从流中删除并\n仍然保留在流中。现在,接下来当您输入您的姓名时,假设Raddicus流的新内容是\nRaddicus。
现在问题来了。当您尝试使用 getline 读取一行时,如果没有提供任何分隔符作为第三个参数,getline 默认读取直到换行符并从流中删除换行符。因此,在调用新行时,getline\n从流中读取和丢弃并导致在 mystr 中读取一个空字符串,它看起来像 getline 被跳过(但事实并非如此),因为流中已经有一个换行符,getline 不会提示输入它已经阅读了它应该阅读的内容。
现在,cin.ignore 在这里有什么帮助?
根据来自cplusplus.com的忽略文档摘录-
istream& ignore (streamsize n = 1, int delim = EOF);
从输入序列中提取字符并丢弃它们,直到提取了 n 个字符,或者一个比较等于 delim。
如果到达文件末尾,该函数也会停止提取字符。如果过早地达到了这一点(在提取 n 个字符或找到 delim 之前),该函数将设置 eofbit 标志。
因此,cin.ignore(256, '\n');, 忽略前 256 个字符或所有字符,直到遇到分隔符(在您的情况下为 \n ),以先到者为准(此处 \n 是第一个字符,因此它会忽略直到遇到 \n )。
仅供参考,如果您不确切知道要跳过多少个字符,而您的唯一目的是清除流以准备使用 getline 或 cin 读取字符串,则应使用cin.ignore(numeric_limits<streamsize>::max(),'\n').
快速解释:它忽略等于流的最大大小的字符或直到遇到 '\n' ,以先发生的情况为准。
Dan*_*Dan 15
你正在考虑这个错误的方法.您每次都在考虑逻辑步骤cin或getline使用它们.防爆.先问一个号码,然后问一个名字.这是错误的思考方式cin.所以你遇到竞争条件,因为你假设每次请求输入时流都是清晰的.
如果你纯粹为输入编写程序,你会发现问题:
void main(void)
{
double num;
string mystr;
cin >> num;
getline(cin, mystr);
cout << "num=" << num << ",mystr=\'" << mystr << "\'" << endl;
}
Run Code Online (Sandbox Code Playgroud)
在上面,你在想,"首先得到一个数字." 所以你输入123按回车键,你的输出就会出现num=123,mystr=''.这是为什么?这是因为在你拥有的流中123\n,当它仍然在流中时被123解析为num变量\n.getline默认情况下,读取doc 函数会istream直到\n遇到a.在这个例子中,因为\n它在流中,看起来它"跳过"它但它正常工作.
要使上述工作正常,您必须输入123Hello World正确输出的内容num=123,mystr='Hello World'.那个,或者你把它放在它cin.ignore之间cin,getline以便它会突破你期望的逻辑步骤.
这就是您需要ignore命令的原因.因为您在逻辑步骤而不是流形式中考虑它,所以您遇到竞争条件.
采取学校常见的另一个代码示例:
void main(void)
{
int age;
string firstName;
string lastName;
cout << "First name: ";
cin >> firstName;
cout << "Last name: ";
cin >> lastName;
cout << "Age: ";
cin >> age;
cout << "Hello " << firstName << " " << lastName << "! You are " << age << " years old!" << endl;
}
Run Code Online (Sandbox Code Playgroud)
以上似乎是合乎逻辑的步骤.首先询问名字,姓氏,然后是年龄.因此,如果您John输入,则Doe输入,然后19输入,应用程序将执行每个逻辑步骤.如果您在"流"中想到它,您只需输入John Doe 19"名字:"问题,它也会起作用,并且似乎跳过剩下的问题.为了使上述步骤按逻辑步骤工作,您需要为ignore问题中的每个逻辑中断提供剩余的流.
记住要记住你的程序输入,因为它是从"流"读取而不是逻辑步骤.每次调用cin它都是从流中读取的.如果用户输入错误的输入,这会创建一个相当错误的应用程序.例如,如果您输入了cin >> double预期a的字符,则应用程序将产生一个相当(看似)怪异的输出.
要手动从输入流中丢弃特定数量的字符时。
一个非常常见的用例是使用它来安全地忽略换行符,因为cin有时会留下换行符,您将不得不移至新的输入行。
长话短说,它为您提供处理流输入时的灵活性。