【问题标题】:Checking for Input Validity?检查输入有效性?
【发布时间】:2014-05-17 15:41:37
【问题描述】:

我想从一个文本文档中读入一个名字、一个空格和一个十进制值的信息。例如,文件中的一行可能有:

虎 56.3

我需要做的是验证第一部分是只包含字母的字符串,第二部分是只包含数字的字符串,包括小数。到目前为止,我有以下基本代码:

ifstream input("data.txt");
while(!input.eof())
{
    string name;
    double score;

    input >> name;
    input >> score;

}

我该怎么做呢?

【问题讨论】:

  • 通常的方法是将文件作为文本读取(可能一次一行),然后自己手动标记和 lex 它。 C++ istream 格式化程序并不真正适合健壮的输入验证。
  • 简单。将行作为字符串输入。按空间分成两部分。循环首先检查非字母和第二个非数字的存在。
  • 你可以使用正则表达式库

标签: c++ validation input


【解决方案1】:

您可能想看看新的C++11Regular Expressions。 它们专门用于输入验证等任务。

检查字符串是否仅包含数字和+- 符号的最小示例如下所示:

#include <iostream>
#include <regex>
#include <string>

int main()
{
    std::string testString;
    std::regex integer("(\\+|-)?[[:digit:]]+");
    input >> testString;
    if(std::regex_match(input, integer))
        std::cout << "Valid number" << std::endl;
    else
    {
        std::cout << "No valid number" << std::endl;
    }
}

但是,您需要一个最新的编译器(我认为是 GCC 4.9)才能使用它们。如果您无法使用,您可以使用Boost Regex Library,它提供了一个非常相似的界面。

【讨论】:

  • 没有 C++11 有什么办法吗?我编写的程序必须在我大学的机器上运行,我认为他们使用的是 C++98。
  • @GdgamesGamers,如果他们安装了 boost,您可以使用 boost 正则表达式库,它类似于新的 C++11 库。如果这也不可用,我认为您将不得不通过迭代字符来对检查进行硬编码......
  • @GdgamesGamers 在答案中添加了链接
【解决方案2】:

将您的数据读入字符串并从那里解析:

std::string name, score_str;
while (input >> name >> score_str)
{
    if (!is_alphabetic(name) || !is_decimal_number(score_str)) {
        // error
    }
    else {
        // convert score_str to a double and assign it to score
    }
}

这是is_alphabetic 的示例:

template<class iter>
bool is_alphabetic(iter beg, iter end)
{
     bool found_number = true;
     while (beg != end && (found_number = !std::isdigit(*beg++)))
        ;
     return found_number;
}

template<class container>
bool is_alphabetic(container& c)
{
    return is_alphabetic(c.begin(), c.end());
}

【讨论】:

    【解决方案3】:
    #include<iostream>
    #include<string>
    using namespace std;
    
    int validate(string,string);
    
    int main(){
    
        string s;
        string d;
    
        cin>>s>>d;
    
        if(validate(s,d)) cout<<"ok";
        else cout<<"not ok";
    
    
    }
    
    
    int validate(string s, string d){
    
    
        for(int i=0;i<s.size();++i){
                //all either small letter or capital letter else error
            if(!((s[i]>='A' && s[i]<='Z') || (s[i]>='a' && s[i]<='z'))){ 
                return 0;
    
            }
    
        }
        int f=0;
    
        for(int i=0;i<d.size();++i){
                //either digits or decimal
            if(!((d[i]>='0' && d[i]<='9') || d[i]=='.')){
                return 0;
            }
    
                //if decimal already present and again decimal its an error ex. 123.23.23
            if(d[i]=='.' && f==1) return 0;
                //flag indicating decimal present
            if(d[i]=='.') f=1;
    
            if(d[i]>='0' && d[i]<='9' && f==1) f=2; // validate decimal like 132. (not valid)
        }
    
        if(f==1) return 0;
    
        return 1;
    }
    

    【讨论】:

      【解决方案4】:

      这里是最简单的代码:

      while(!input.eof())
      {
      
          string name;
          string score;
      
          input >> name;
          for (int i=0; i<name.size() ; i++) {
              if ( ( name [i] >= 'A' && name [i] <= 'Z' ) || ( name [i] >= 'a' && name [i] <= 'z' ) || (name [i] == '_') ) {
                  continue;
              } else {
                  cout <<"Name is not valid!";
                  break;
              }
          }
      
          input >> score;
          for (int j=0; j<score.size() ; j++) {
              if ((score [j] >= '0' && score [j] <= '9') || (score[j]=='.') ) {
                  continue;
              } else {
                  cout <<"Number is not valid!";
                  break;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 2020-12-25
        • 2017-04-13
        • 2014-02-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多