Thread: Check for letters

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    1

    Check for letters

    Don't really know how to word this but I'll try my best...

    I made a simple little program after reading a few tutorials that asks for some information and then does some math etc.

    One question asks for your age and you could put in: 15 years and it would crash because of the word 'years'. Is there a way I can ignore any words and only take the numbers?

  2. #2
    Registered User Sake's Avatar
    Join Date
    Jan 2005
    Posts
    89
    You'll want to validate the input one way or another and ignore it or not depending on whether it's a number. The easiest way to do this is to test a call to cin's >> operator.
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int x;
    
      while (cin>> x)
        cout<< x <<endl;
    }
    However, if you want to keep taking input after the non-number then you need to do a little more work. The most common method is to read everything as a line, then parse it.
    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    int main()
    {
      string line;
      int x;
    
      while (getline(cin, line)) {
        istringstream in(line);
        if (in>> x)
          cout<< x <<endl;
      }
    }
    Again, there's a problem. What if you want to allow for more than one number in a line, and you still want to ignore any invalid numbers? Once again, it's harder:
    Code:
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    
    class Split {
    public:
      typedef std::vector<std::string>::iterator iterator;
      typedef std::vector<std::string>::const_iterator const_iterator;
    public:
      Split(const std::string& s, const char sep);
    public:
      iterator begin() { return split.begin(); }
      const_iterator begin() const { return split.begin(); }
      iterator end() { return split.end(); }
      const_iterator end() const { return split.end(); }
    private:
      std::string original;
      std::vector<std::string> split;
    };
    
    Split::Split(const std::string& s, const char sep)
      : original(s)
    {
      std::istringstream in(original);
      std::string token;
    
      while (getline(in, token, sep))
        split.push_back(token);
    }
    
    using namespace std;
    
    int main()
    {
      string line;
      int x;
    
      while (getline(cin, line)) {
        Split t(line, ' ');
        for (Split::const_iterator it = t.begin();
          it != t.end(); ++it)
        {
          istringstream in(*it);
          if (in>> x)
            cout<< x <<endl;
        }
      }
    }
    Fortunately, if you do it carefully then you can reuse the code for splitting up a line.
    Kampai!

  3. #3
    Whats gonna happen now! himanch's Avatar
    Join Date
    Feb 2005
    Location
    Armenia
    Posts
    26
    yes i completely agree with Sake!!!

    i think there is no word to add!!!
    Hayda!!!Whats gonna happen tomorrow

  4. #4
    Registered User Scribbler's Avatar
    Join Date
    Sep 2004
    Location
    Aurora CO
    Posts
    266
    Why not do something simple like....

    Code:
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int x;
    	char ch;
    		
    	while ( ( ch = cin.get() ) != '\n' )
    	{
    		
    		cin.putback(ch);
    		
    		if ( isdigit( ch ) )
    		{
    			cin >> x;
    			cout << x << " ";
    		}
    		else
    			cin.ignore();
    	}
    		
    	return 0;
    }

  5. #5
    Registered User Sake's Avatar
    Join Date
    Jan 2005
    Posts
    89
    >>Why not do something simple like....
    Because it's false simplicity. The logic is surprisingly hard to follow for such seemingly easy code. It's harder to get an algorithm right when you have to parse as you go, and it's worse when you both read and unread characters from the stream. Case in point, your code has a bug when it comes to EOF.
    Kampai!

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Code:
        while ( ( ch = cin.get() ) != '\n' )
        {
            
            cin.putback(ch);
    Or you could avoid a lot of problems by using cin.peek() instead of cin.get() and then removing the putback

    Though as Sake said, the logic is still bad

  7. #7
    Registered User Scribbler's Avatar
    Join Date
    Sep 2004
    Location
    Aurora CO
    Posts
    266
    Originally I was going to post....
    Code:
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int x;
            
        while ( cin.peek() != '\n' )
        {
            
            if ( isdigit( cin.peek() ) )
            {
                cin >> x;
                cout << x << " ";
            }
            else
                cin.ignore();
        }
            
        return 0;
    }
    But eventually I found myself inserting a switch to catch characters that would parse floating point, hex, octal numbers (case in point, 3.14159 would be input as int 3 and int 14159 seperately), then realized it was getting more complicated than the original poster was looking for. So then I cut out chunks of code and replaced it with the putback. So yeah, I left it polluted. (My memory of last night is a bit...obscured, but I seem to recall reasoning leaving it that way so as to facillitate added functionality. In hindsight, not my brightest idea ever)

    However aside from the extra junk I left, what logic error is there? As applies to the OP's needs that is.
    Last edited by Scribbler; 02-06-2005 at 03:59 PM.

  8. #8
    Registered User Sake's Avatar
    Join Date
    Jan 2005
    Posts
    89
    >>what logic error is there?
    cin.get() returns an int_type, not char. It's a variant of the "getchar returns int" confusion in C.
    Kampai!

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It's not confusing at all. EOF cannot fit in a char. If it could, then it could be written randomly throughout the middle of the file, corrupting it or any stream using characters. It can't be something that will simply fit in a byte.

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BN_CLICKED, change button style
    By bennyandthejets in forum Windows Programming
    Replies: 13
    Last Post: 07-05-2010, 11:42 PM
  2. How can i check a directory for certain files?
    By patrioticpar883 in forum C++ Programming
    Replies: 13
    Last Post: 02-01-2008, 05:27 PM
  3. how to check input is decimal or not?
    By kalamram in forum C Programming
    Replies: 3
    Last Post: 08-31-2007, 07:07 PM
  4. Please check this loop
    By Daesom in forum C++ Programming
    Replies: 13
    Last Post: 11-02-2006, 01:52 AM
  5. how to check for end of line in a text file
    By anooj123 in forum C++ Programming
    Replies: 6
    Last Post: 10-24-2002, 11:21 PM