更新
我找到了问题的原因.我一直在尝试用鱼贝.我看到有人说在Mac上成功运行我的代码的评论,并决定在标准的bash shell中尝试它.它工作得很好.所以,我猜没有鱼壳了.:)
我仍然很想知道cin如何以及为什么以它的方式工作.这是我提问的主要部分.
我遇到了一个流行的问题:cin在循环中使用.代码很简单,但我找不到解决方案.这些问题的答案谷歌已经提供我是多种多样的,但通常涉及的一些组合cin.clear(),cin.ignore()和cin.get().不幸的是,我无法找到解决问题的组合或排序.而且,我觉得令人沮丧的是我没有完全理解它的功能cin.我宁愿不使用反复试验来解决这个问题.我想知道到底发生了什么.
应该发生什么
当我运行我的代码时,我应该看到一个带有选项列表的提示.我应该能够输入一个将运行其中一个选项的角色.然后,它应该再次显示提示并重复该过程,直到我选择退出选项.
实际发生了什么
一旦我运行代码,它会立即向屏幕打印提示,并最终在提示的中途停止.然后我无法做任何事情,但杀了它^C.
$ ./run
Choose an option:
[A]dd a score
[R]emove a player
[E]xit
: That is not a valid input.
[repeated a bunch of times]
Choose an option:
[A]dd a score
[R]emove a player
[E]xit
: That is not a valid input.
Choose ^C
$
Run Code Online (Sandbox Code Playgroud)
我的问题
是什么导致cin这样做?作为一名经验丰富的Java开发人员(但是初学C++开发人员),我熟悉缓冲区和流的概念等,但我不知道它是如何cin工作的.我知道cin.clear()清除错误状态,并cin.ignore()忽略流中的许多字符.到目前为止,我的Google-fu无法找到简明的参考资料.
为什么cin按照它的方式行事?如何cin在循环中使用时可视化引擎盖下发生的事情?在C++中实现这种无限菜单思想的最优雅方式是什么?
我的守则
这是我的代码的简化版本,它产生与完整版本完全相同的问题:
#include <iostream>
using namespace std;
int main () {
//infinite menu
char input;
while(true) {
//prompt
cout << "\n\nChoose an option:\n";
cout << "[A]dd a score\n";
cout << "[R]emove a player\n";
cout << "[E]xit\n";
cout << "\n\t: ";
//input
cin >> input;
//decide what the input means
switch(input) {
case 'a':
case 'A':
cout << "Add a score.\n";
break;
case 'r':
case 'R':
cout << "Remove a player.\n";
break;
case 'e':
case 'E':
cout << "Program Complete.\n";
return 0;
break;
default:
cout << "That is not a valid input.\n";
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我编译并运行:
$ g++ Test.cpp -o run
$ ./run
Run Code Online (Sandbox Code Playgroud)
我gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)在Mac OS X 10.8.2上运行.
帮自己一个忙,不要直接从中提取令牌std::cin.相反,读与行线getline和再解释每一行.此外,您必须始终在布尔上下文中评估输入操作的结果,否则您将无法正确处理任意输入.
对于测试,如果您打电话,您的计划必须存在echo "abc" | ./run.这应该是您的第一次测试之一.
现在,代码:
#include <string>
#include <iostream>
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
if (line.empty()) { continue; }
if (line == "A" || line == "a") { /* ... */ continue; }
if (line == "R" || line == "r") { /* ... */ continue; }
if (line == "E" || line == "e") { break; }
std::cout << "Sorry, I did not understand.\n";
}
std::cout << "Goodbye!\n";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1456 次 |
| 最近记录: |