如何安全地使用 cin 与字符。

huangapple go评论49阅读模式
英文:

How to "safely" use cin with a char

问题

这似乎是一个愚蠢的问题,但我找不到关于这个的太多信息。

我的代码接受用户输入,只期望接收't''f'

我很难"保护"程序免受边缘情况的影响(例如,如果输入包含多个字符和/或空格,它将循环遍历缓冲区中的每个char,直到找到't''f')。

我理解使用cin.fail()仅适用于int。是否有类似的东西我可以用于char?我希望类似于这样的东西起作用。我只是很难弄清楚如何在这种情况下定义cin的错误/失败,以及如何阻止它循环遍历整个缓冲区。

char choice = '0';
while(choice != 't' && choice != 'f') {
    std::cout << "Is this answer true or false? (t/f) ";
    std::cin >> choice;
    
    if (error_with_input) {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Error. char not entered. Please try again";
    }
}

我是不是从错误的角度来看待这个问题?我应该只是将choice变量更改为string而不是char吗?然后我可以使用getline(),测试choice的长度是否为1,如果是,然后最终测试choice是否为't''f'。这似乎有点低效,但也许这是一个更好的解决方案?

英文:

This seems like a dumb question, but I can't find much info about this.

My code takes user input, and only expects to receive &#39;t&#39; or &#39;f&#39;.

I have a hard time "protecting" the program from edge cases (ex: if the input contains multiple characters and/or spaces, it will loop through every char in the buffer until it finds &#39;t&#39; or &#39;f&#39;).

I understand that using cin.fail() only works for an int. Is there something similar that I could use for a char? I would like if something along the lines of this worked. I'm just having a hard time figuring out how to define an error/failure of cin in this case, and how to stop it from looping through the entire buffer.

char choice = &#39;0&#39;;
while(choice != &#39;t&#39; &amp;&amp; choice != &#39;f&#39;) {
    std::cout &lt;&lt; &quot;Is this answer true or false? (t/f) &quot;;
    std::cin &gt;&gt; choice;
    
    if (error_with_input) {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), &#39;\n&#39;);
        std::cout &lt;&lt; &quot;Error. char not entered. Please try again&quot;;
    }
}

Am I looking at this from the wrong point of view? Should I just make the choice variable a string instead of a char? I could then use getline(), test if choice has a length of 1, and if so then finally test if choice is either &#39;t&#39; or &#39;f&#39;. It seems a little inefficient, but maybe it's a better solution?

答案1

得分: 2

读取输入作为 std::string,或者至少作为 char[],这是正确的方法。在读取之后验证输入,而不是在读取时验证,例如:

std::string choice;
do {
    std::cout << "这个答案是真还是假? (t/f) ";
    std::cin >> choice;
    
    if (choice != "t" && choice != "f") {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "错误。未输入字符。请重试";
    }
    else {
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        break;
    }
}
while (true);
英文:

Reading the input as a std::string, or at least as a char[], is the right way to go. Validate the input after you have read it in, not while you are reading it, eg:

string choice;
do {
    std::cout &lt;&lt; &quot;Is this answer true or false? (t/f) &quot;;
    std::cin &gt;&gt; choice;
    
    if (choice != &quot;t&quot; &amp;&amp; choice != &quot;f&quot;) {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), &#39;\n&#39;);
        std::cout &lt;&lt; &quot;Error. char not entered. Please try again&quot;;
    }
    else {
        std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), &#39;\n&#39;);
        break;
    }
}
while (true);

huangapple
  • 本文由 发表于 2023年4月4日 12:04:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定