带有 + 的 Cin 输入导致下一个输入为字符串

Cin input with a + causes next input to be a string

所以我是 C++ 的新手,我正在为我的 class 做作业。我 运行 在尝试检查输入是字符串还是 double/int 时遇到问题。所以我做了一个基本程序来测试它

#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
    string hi;
    double hello;

    cin >> hello;

    if (!cin)
    {
        //Strings go here

        cin.clear();
        cin >> hi;
        cout << hi << endl;
    }
    else
    {
        cout << hello << endl;
    }

    cout << "Done!" << endl;
}

所以它基本上在输入字母(例如"j"或"a")或数字时有效,但在输入“+”或“-”时它会等待下一个输入然后强制它通过字符串块,即使它是一个数字。但是“*”或“/”被读取为字符串并且不会导致该问题(我假设因为它们不是明确的运算符) 我想我可能遗漏了一些东西。谢谢


编辑:我一次测试单一类型(例如 123、1、d、+)而不混合类型,因此不会有任何具有双精度和字符串的输入

根据 user4581301 的建议,我将放入一些示例输入和输出

输入:输出

"Hello":"Hello"

123:123

"/":"/"

"+" (在: 2之后输入):"2"

问题

您的程序没有完全按预期运行,因为它没有考虑可能消耗但丢失的字符。

以下是按预期工作的不同案例:

  • abc:读取的第一个字符不是数字,因此不会被消耗并且 cin 很快失败。第二次读取读取作为字符串存在的每个字符。
  • 123abc456:读取第一个123。当遇到 a 时,它不会被消耗,因为它不是有效的数字。进一步阅读停止,但可以读取数值。
  • /123:读取的第一个字符不是数字,所以它没有被消耗,cin 失败。第二次读取读取作为字符串存在的每个字符。
  • -123+123:第一个字符被认为是有效的数字字符并被读取,然后读取其余部分,仍然是一个数值。如果您认为可以对 double 或 int 进行签名,则按预期工作。根据输出格式,+ 可能不会出现在您的输出中。

以下是不起作用的情况:如果第一个字符是 +- 但它后面没有有效的数字字符。在这种情况下,第一个字符被消耗,但下一个字符使数字输入失败。然后将剩余的字符作为字符串读取(除了已经消耗并丢失的第一个符号)。示例:

  • ++123
  • + 123(space 结束提取失败的 double,余数作为字符串读取)。

Online demo

解决方案

最简单的解决方案是将输入读取为字符串,然后尝试转换该字符串。

例如:

size_t processed;
string hi;
double hello;
cin >> hi;

try {
    hello = stod(hi,&processed); 
    cout<<"number:" <<hello; 
    if (processed<hi.size()) 
        cout << " (followed by something)";
    cout <<endl; 
}
catch (...)   // should be more precise in catching, but it's for the proof of concept 
{
    cout <<"string: "<< hi << endl;
}

Online demo

如果您想将 + 和 - 视为字母数字,则在尝试进行转换之前检查 hi 是否为非空以及 hi[0] 是否为数字会很容易。

或者,您也可以对字符串进行 regex 检查,看它是否与数字格式匹配。