简体   繁体   English

Cin in a while 循环

[英]Cin in a while loop

So, I've looked around and haven't been able to figure out what's going on with cin during my While loop.所以,我环顾四周,无法弄清楚在我的 While 循环中 cin 发生了什么。 I'm working through the book C++ Primer (5th edition) and I noticed that during one of the exercises I couldn't use cin to grab strings without it not terminating the while loop.我正在阅读《C++ Primer》(第 5 版)这本书,我注意到在其中一个练习中,我无法使用 cin 来抓取字符串,除非它不终止 while 循环。 I fixed this issue by just using getline().我通过使用 getline() 解决了这个问题。

The goal of the current exercise is to ask for user input from the values of 0 - 15, and converting that number into it's "Hex Equivelant" (Where 0 = 1, 1 = 2, 2 = 3, ... , 10 = A, 11 = B).当前练习的目标是要求用户输入 0 - 15 的值,并将该数字转换为“Hex Equivelant”(其中 0 = 1, 1 = 2, 2 = 3, ... , 10 = A, 11 = B)。 I tried doing this without the book and failed, but then started questioning the code in the book.我尝试在没有这本书的情况下执行此操作并失败了,但随后开始质疑书中的代码。 Here's the code in the book:这是书中的代码:

//Note: <iostream> and <string> have been included. using namespace std is used 
const string hexdigits = "0123456789ABCDEF";
cout << "Enter a series of numbers between 0 and 15"
     << " separated by spaces. Hit ENTER when finished: "
     << endl;
string result;
string::size_type n;

while(cin >> n)
    if (n < hexdigits.size())
        result += hexdigits[n];
cout << "Your hex number is: " << result << endl;

If I were to run this code, it would never terminate the while loop after hitting enter without entering any code (essentially giving the input of whitespace I would think?).如果我要运行这段代码,它永远不会在没有输入任何代码的情况下按 Enter 键后终止 while 循环(基本上是输入我认为的空格?)。

I'm here for two reasons:我来这里有两个原因:

1) Why does this code not work? 1)为什么这段代码不起作用? 2) I would appreciate a nudge in the right direction, but not the answer to how to get this code to execute correctly 2)我希望朝着正确的方向轻推,但不是如何让这段代码正确执行的答案

If I can't receive reason 1 without compromising reason 2, I would much rather have reason 1 be fulfilled.如果我不能在不妥协原因 2 的情况下接受原因 1,我宁愿让原因 1 得到满足。

Quick-Edit: I apologize, I'm using Visual Studio 2012快速编辑:抱歉,我使用的是 Visual Studio 2012

As long as you enter valid numbers it will continue to read numbers.只要您输入有效数字,它就会继续读取数字。 You can terminate the loop by entering something which isn't a number, eg, "goodbye".您可以通过输入非数字内容来终止循环,例如“再见”。 At the beginning of a line, ie, immediately after hitting enter you should also be able to terminate the standard input using Ctrl-Z (I think; I normally work on UNIX-like systems where you'd terminate the standard input using Ctrl-D).在一行的开头,即,在按下 Enter 键后,您还应该能够立即使用 Ctrl-Z 终止标准输入(我认为;我通常在类 UNIX 系统上工作,在这种系统中您会使用 Ctrl-终止标准输入) D)。

Essentially, a stream converts to true as long as neither std::ios_base::failbit nor std::ios_base::badbit is set in its state (you can look at stream 's state using stream.rdstate() ).本质上,只要std::ios_base::failbitstd::ios_base::badbit都没有设置在其状态(您可以使用stream.rdstate()查看stream的状态stream.rdstate() ,流就会转换为true As long as you successfully read integers from the stream, it has no reason to go into failure state.只要您成功地从流中读取整数,就没有理由进入失败状态。 When you enter something which isn't an integer, it will get std::ios_base::failbit set.当您输入不是整数的内容时,它将设置std::ios_base::failbit Likewise, when it reaches the end of the stream.同样,当它到达流的末尾时。

@Protomega,您可以使用相同的代码,但按 Ctrl+D 停止输入流。

Hitting Enter produces either a CR or LF or both, depending on your platform.按 Enter 会产生 CR 或 LF 或两者,具体取决于您的平台。 This is a valid input so satisfies the condition to continue the while loop.这是一个有效的输入,因此满足继续 while 循环的条件。 You will need to either explicitly test for these characters at the beginning of your input or use Ctrl-C to break out of the loop.您需要在输入开始时显式测试这些字符,或者使用 Ctrl-C 来跳出循环。

As a readability issue, I would include braces around the code that you want in the loop.作为可读性问题,我会在循环中所需的代码周围包含大括号。 What you have there is valid C++ since without braces the while will loop on the next statement and the whole if conditional is a single statement.您拥有的是有效的 C++,因为没有大括号, while将在下一个语句上循环,并且整个if条件是单个语句。 Practice putting them in now even on single line loops and you'll save yourself some headache debugging in the future.现在练习将它们放入单行循环中,将来您将省去一些麻烦的调试工作。

There is an easier way to do this:有一种更简单的方法可以做到这一点:

const string hexdigits = "0123456789ABCDEF";
cout << "Enter a series of numbers between 0 and 15 separated by spaces. Hit ENTER when finished: " << endl;
string line;
string result;
if (getline(cin, line)) // get the whole line
{
    istringstream iss(result); // break them by spaces
    int i;
    while (iss >> i)
    {
        result += hexdigits[i];
        result += " ";
    }
    cout << "Your hex result:  " << result << endl;
}
else
{
    cout << "Error handling input!" << endl;
}

With your solution, you would need to press Ctrl-D to end the input.对于您的解决方案,您需要按 Ctrl-D 来结束输入。

CTRL-D works on Linux. CTRL-D 适用于 Linux。 A simpler code snippet is below:一个更简单的代码片段如下:

vector<double> vd;
for (double d; cin>> d;)
     vd.push_back(d);
for(int i=0; i<vd.size(); ++i)
   cout << vd[i] << endl;

In while (cin >> n) think separately of While() as a loop and what stands within it's parenthesis.while (cin >> n)将 While() 视为一个循环以及它括号内的内容。 When Loop begins you are moved into parentheses and asked to enter something by cin.当 Loop 开始时,您会被移到括号中,并要求 cin 输入一些内容。 This happens every time loop begins.每次循环开始时都会发生这种情况。 There is no way to terminate looping in this case.在这种情况下没有办法终止循环。 It is the same as i would say:这和我想说的一样:

while (/*some condition*/) {
cin >> n; // this is always valid, true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM