【问题标题】:c++ template input validationc++模板输入验证
【发布时间】:2011-10-17 22:51:59
【问题描述】:

我正在使用以下内容轻松提取输入并验证正确的类型。但是,文件 EOF 的结尾没有被触发。

template< typename T >
std::istream& read(std::istream &istr, T &val)
{
    std::string s;
    std::getline(istr, s);

    if (istr.good())
    {
        s.erase(s.find_last_not_of(" \n") + 1);

        std::stringstream iss(s);

        iss >> val;

        if (! iss.good())
            istr.setstate(std::ios::failbit);

        char c;
        if (iss.get(c))
            istr.setstate(std::ios::failbit);
    }

    return istr;
}
int main(int argc, char **argv)
{
    int input = 0;

    std::cout << "Please enter an integer>" << std::flush;

    for (;;)
    {
        if (read(std::cin, input))
            break;

        std::cin.clear();
        std::cout << "Please, enter only an INTEGER>" << std::flush;
    }

    std::cout << "Press <enter> to quit>";
    std::cin.ignore(std::numeric_limits< std::streamsize >::max(), '\n');
    return 0;
}

输入的“111”在应该验证为整数时没有验证。

【问题讨论】:

  • 这也无法获取单个字符。

标签: c++ validation templates input


【解决方案1】:

iss &gt;&gt; val 读取所有字符并“触及”流的末尾,因此每次都会触发 EOF。

template< typename T >
std::istream& read(std::istream &istr, T &val)
{
    std::string s;
    std::getline(istr, s);

    if (istr.good()) {
        std::istringstream iss(s); //leave the '\n'

        if (! (iss >> val))
            istr.setstate(std::ios::failbit);

        //if it gets another character that isn't a newline
        char a=0;
        if (iss.get(a) && a!='\n') 
            istr.setstate(std::ios::failbit);
    }

    return istr;
}

【讨论】:

  • 如果我将输入类型更改为 int,并输入“1”(注意空格)它会接受它,但它不应该这样做。
  • @rem45acp :如果您希望空格 很重要,那么标准 I/O 流不是适合该工作的工具。试一试Boost.Spiritauto_ 解析器。
  • 所有格式化的输入都会跳过空格。如果您不想允许空格,则必须使用未格式化的输入编写自己的例程。
  • 你说得对,那里的空间并不重要。但是,现在放置 iss.get(a) 会破坏整数的函数。在我的原始帖子中查看我的编辑。
  • @rem45acp:我自己做了测试,但问题并不是我想的那样。已更正。
猜你喜欢
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
相关资源
最近更新 更多