Link to home
Start Free TrialLog in
Avatar of shykumar
shykumar

asked on

How to check if C++ string has junk values

Hi,

I need to check if the string has wrong/junk values. How can I do it?

My string should have only integer values in them.

Example:
std::string s1="1234"      //This is a valid value
std::string s2="123a"      //This or any combination (including control characters) is not valid

I am using C++ (GNU compiler) and Linux.

thanks,
Sreeni
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of phoffric
phoffric

re:
======================
std::string s2="123a";
int test;
std::stringstream ss(s2);
ss >> test;
======================
    This gives 123 since only valid chars making up an integer will be read in.
But the next attempt to do a ss >> test should fail due to the 'a'.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Please try this:
try
{
     i1 = atoi (s1);   //try converting string to integer
}


It is up to you if you want to use just "catch" with it to display the error message or want to "throw" and then catch.  It is up to your design.

Another observation,

Just use namespace std, it makes life much easier and syntax beautiful.

So you can have
#include <iostream>
#include <string>

using namespace std;


int main()
{


}

.....

Hope it helps
>> It is up to you if you want to use just "catch" with it to display the error message or want to "throw" and then catch.  

atoi doesn't throw - it is a C function. Further, how will you distinguish 0 from non-numeric values that will also be reported as 0?
Ok.  Please disregard the try part.

I think the best way is to use "at" member function and testing each character to individually if it is between 0 and 9.  Make a small function IsNum, if you want to test it.  If you don't care to test, atoi should ignore trailing garbage.  So 1234abc should change to 1234.

if s is the string, atoi(s.c_str())
>> I think the best way is to use "at" member function and testing each character to individually if it is between 0 and 9.

What "at" member function?

Seriously, why reinvent the wheel? string already has two perfectly good functions to do this as I explained above! http:#33737718
I don't think I am reinventing the wheel.  May be I missed but I don't think there is a member function to test whether string is an integer.  The function atoi() removes any trailing garbage.

With "at" you can.  I know you can do it without "at".  It is just made for this purpose.

//Is number
bool success = true;
for(int i = 0; i < s.length(); i++)
{
    if( s.at(i) < 0 || s.at(i) > 9 )
    {
        success = false;
        break;
    }
}

//If success == false, it was not an integer.
>> The function atoi() removes any trailing garbage.

The asker isn't asking to convert (which might be one reason to want to remove "trailing garbage") they are asking "How to check if C++ string has junk values" and you just cannot do this (properly) with atoi because it will always return you a number.

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Return Value

On success, the function returns the converted integral number as an int value.
If no valid conversion could be performed, a zero value is returned.
If the correct value is out of the range of representable values, INT_MAX or INT_MIN is returned.

So how does that tell you if it contains "junk"?

>> May be I missed but I don't think there is a member function to test whether string is an integer
http://www.cplusplus.com/reference/string/string/find_first_not_of/
Look at the example they provide. A modified version is below, which will solve the askers problem.


string s ("");
if ( s.find_first_not_of("0123456789") != string::npos )
{
    // contains a non-numeric value
}

Don't you agree that is a lot simpler than what you posted previously?

>> With "at" you can.
Sorry, just realised you were referring to the member function on string. Yes, you can use that to access the individual characters in the string - but you don't need to do this for solving this problem as string already has a member to do this.
bool isNum(const char* p)
{
      istringstream s(p);
      double d;
      s >> d;
      return s && s.rdbuf()->in_avail() == 0;
}
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.