0

假设我希望用户输入一个整数,但他输入了一个双精度值或字符值,我如何检查用户输入的类型是否正确。

string line;
getline(cin, line);
// create stringstream object called lineStream for parsing:
stringstream lineStream(line); 
string rname;
double res;
int node1,node2;
lineStream >> rname >> res >> node1 >> node2;

如何检查有效的输入类型?

4

3 回答 3

1

您检查流是否正常:

if (lineStream >> rname >> res >> node1 >> node2)
{
    // all reads worked.
}

您可能希望最后检查垃圾。

if (lineStream >> rname >> res >> node1 >> node2)
{
    char x;
    if (lineStream >> x)
    {
         // If you can read one more character there is junk on the end.
         // This is probably an error. So in this situation you
         // need to do somethings to correct for this.
         exit(1);
    }

    // all reads worked.
    // AND there is no junk on the end of the line.
}

评论扩大。

从下面的评论:

如果我为 rname 输入一个整数,它仍然有效。例如:

string line; getline(cin, line);
stringstream lineStream(line); // created stringstream object called lineStream for parsing
string rname; 
if (lineStream >> rname) { cout << "works"; }

让我们假设有一些属性rname可以让我们将它与数字区分开来。例如:它必须是一个名字。即它必须只包含字母字符。

struct Name
{
    std::string   value;
    friend std::istream& operator>>(std::istream& s, Name& data)
    {
        // Read a word
        s >> data.value;

        // Check to make sure that value is only alpha()
        if (find_if(data.value.begin(), data.value.end(), [](char c){return !isalpha(c);}) != str.end())
        {
            // failure is set in the stream.
            s.setstate(std::ios::failbit);
        }
        // return the stream
        return s;
    }
};

现在您可以读取名称。

Name rname; 
if (lineStream >> rname) { cout << "works"; }

如果您为 rname 输入整数,这将失败。

延伸答案

如果您有多行相同的信息要阅读。然后值得将其包装在一个类中并定义一个输入流运算符。

strcut Node
{
    Name   rname;
    double res;
    int    node1;
    int    node2;

    friend std::istream& operator>>(std::istream& s, Node& data)
    {
        std::string line;
        std::getline(s, line);

        std::stringstream linestream(line);
        lineStream >> data.rname >> data.res >> data.node1 >> data.node2;

        if(!linestream)
        {
            // Read failed.
            s.setstate(std::ios::failbit);
        }
        return s;
    }
};

现在很容易阅读循环中的行:

Node n;
while(std::cin >> n)
{
    // We read another node successfully
}
于 2013-09-28T15:52:02.267 回答
0

由于字符串 123 也将被视为字符串,而不是整数,因此更好的方法是迭代字符串以结束,直到找到任何非数字字符。您可以这样做:

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}
于 2013-09-28T16:11:10.427 回答
0

先将 node1 和 node2 读入字符串,然后用正则表达式验证。

#include <regex>
...
string node1_s, node2_s;
linestream >> rname >> node1_s >> node2_s
if (regex_match(node1_s, regex("[+-]?[0-9]+") {
    /* convert node1_s to int */
} else {
    /* node1_s not integer */
}
/* Do same for node2_s */
于 2013-09-28T16:27:23.870 回答