C ++变量检查

时间:2013-09-28 15:49:42

标签: c++

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

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;

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

3 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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();
}

答案 2 :(得分: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 */