0

I am suppose to read in from a text document information written as a name , a space, and a decimal value. For example, a line from a file might have:

Tiger 56.3

What I need to do is validate that first part is a string containing only letters and second part containing only digits including decimals. I have the following basic code so far:

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

    input >> name;
    input >> score;

}

How do I go about doing this ?

3
  • The usual way is to read the file in as text (perhaps a line at a time) and then to manually tokenise and lex it yourself. The C++ istream formatters are not really suitable for robust input validation. Commented May 17, 2014 at 15:43
  • Simple. Input the line as a string. Divide into two parts by the space. Loop over first to check presence of non-letters and second non-digits. Commented May 17, 2014 at 15:50
  • You can use regex library Commented May 17, 2014 at 15:53

4 Answers 4

1

You may want to have a look at the new C++11 Regular Expressions. They are specifically made for tasks like input validation.

A minimal example to check if a string contains only digits and + or - signs could look like this:

#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;
    }
}

However you need a very recent compiler (GCC 4.9 I think), to use them. If this is unavailable to you, you can use the Boost Regex Library, it provides a very similar interface.

Sign up to request clarification or add additional context in comments.

3 Comments

Any way to do it w/o C++11? The program I write has to run on my University's machines and I think they are using C++98.
@GdgamesGamers, If they have boost installed, you can use the boost regex library, which is similar to the new C++11 library. If this is unavailable too, I think you will have to hard code the check by iterating of the characters...
@GdgamesGamers Added Link in the answer
0

Read your data into strings and parse it from there:

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
    }
}

Here's an example of 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());
}

Comments

0
#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;
}

Comments

0

Simplest code here it is:

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;
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.