【问题标题】:How to deal with this side effect?如何处理这种副作用?
【发布时间】:2014-02-08 12:29:10
【问题描述】:
char sign;
cout << "Enter '+' for addition or '-' for subtraction: ";
cin >> sign;
if ( sign != '+' && sign != '-' ) {
     cout << "you can only enter '+' or '-'!\n";
     return 1;
}

如果我输入+32423,输入的cin仍然是正确的(它会通过检查),因为+会被自动设置为符号变量,并且32423也会被存储到我的下一个变量(如果有):

cin >> number;

如何更改代码以使+32423cin 不正确?

【问题讨论】:

  • 使用string 来获取输入。并检查string == +/-
  • 我没有看到任何副作用。

标签: c++ iostream cin


【解决方案1】:

您需要准确地确定您需要用户输入的内容以及使输入有效的原因。在我看来,您想接受用户的一整行输入(因此您应该使用std::getlinestd::string),然后您只想接受恰好是"+""-" 的字符串。

std::string sign;
std::getline(std::cin, sign); // Gather input
if (sign != "+" && sign != "-") { // Parse input
  // ...
}
// ...

正如@H2C03 提到的,将输入和解析分开是个好主意。在这种情况下,解析就像将输入行与字符串 "+""-" 进行比较一样简单。

【讨论】:

  • 所以我应该使用 string 而不是 char 和 getline 而不是 cin?
  • @Joshua 不,您需要使用 cin 来获取您的输入。查看我的编辑。
  • @JosephMansfield 不,他确实应该改用getline(),以获得一行输入。
【解决方案2】:

不要试图一步做两件事。这是一个常见的错误——不要觉得太糟糕,scanf() 系列函数和std::istream::operator&gt;&gt; 的设计者犯了完全相同的错误。

您正在尝试做的事情:获取用户输入并对其进行解析以执行计算。

实际上在做什么:您正在一步完成这些完全不同的事情,这让您感到困惑。相反,您应该清晰地分开这两个步骤:首先,获取用户输入,然后正确解析它。如:

// get an entire line
std::string line;
std::getline(std::cin, line);

// parse it: only the format <some digits> <'+' or '-'> <other digits>
// is acceptable, most probably with interspersed whitespace
std::string::iterator it = line.begin();
while (isspace(*it) && it != line.end())
    it++;

std::string::iterator it2 = it;
while (isdigit(*it) && it != line.end())
    it++;

std::string first_number(it2, it); // construct a new substring for the 1st number

// etc. continue the parsing in a similar manner

【讨论】:

  • 我很确定他们只希望能够接受单个 + 或单个 -,因此解析就像将输入行与这两个单个字符串进行比较一样简单.
  • @JosephMansfield 那么你是说12345 + 12345 也不正确吗?我认为根本不是这种情况——OP 非常清楚,非常明显想要执行一些算术运算。但即便如此——何必呢?我关于“​​分两步做”的建议仍然适用,而且那时更容易实现。
  • 是的,我认为这也是不正确的。他们只想要运营商。他们接下来会得到操作数。
猜你喜欢
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2013-07-14
相关资源
最近更新 更多