Thread: Input check problem with numbers

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    66

    Input check problem with numbers

    Which is the most suitable source code? I need a programmer with a large experience on C++ to answer this question.

    Code:
    #include <string>
    #include <iostream>
    #include <limits>
    
    int main()    {
        using namespace std;
        const int THISYEAR = 2007;
        string yourName;
        int birthYear,bad_input;
        
        cout << "What's your name ? " << flush;
        getline(cin, yourName);
    
       
        do {
          
            bad_input=0;
            cout <<"\nWhat year were you born :" << flush ;
            cin >> birthYear;
            if(!cin.good())   
            {
              
                bad_input=1;
                cin.clear();   
               
           
                cin.ignore(numeric_limits<streamsize>::max(),'\n');
                cout << "This is not valid value" << endl;
            }
        }while(bad_input);
           
        cout << "Your name is " << yourName
             << " and you are approximately "
             << (THISYEAR-birthYear)
             << " years old. " << endl;
       
        return 0;
    }

    2nd:
    Code:
    #include <string>
    #include <iostream>
    #include <limits>
    
    int main()	{
    	using namespace std;
    	const int THISYEAR = 2007;
    	string yourName;
    	int birthYear;
    	
    	cout << "What's your name ? " << flush;
    	getline(cin, yourName);
    			
    	cout <<"What year were you born? " << flush;
    	while(!(cin>>birthYear))	
    	{
    		cin.clear();	
    		cin.ignore(numeric_limits<streamsize>::max(),'\n');
    				
    		cout << "No valid value. ";
    		cout <<"What year were you born? " << flush;
    	}
    			
    	cout << "Your name is " << yourName
    		 << " and you are approximately "
    		 << (THISYEAR-birthYear)
    		 << " years old. " << endl;
    	
    	return 0;
    }

    3rd
    Code:
    #include <string>
    #include <iostream>
    #include <cstdlib>
    
    int main()    {
        using namespace std;
        const int THISYEAR = 2007;
        string yourName;
        int birthYear;
        char temp[100];
       
        cout << "What's your name ? " << flush;
        getline(cin, yourName);
       
        do    {
            cout <<"What year were you born? " << flush;
            cin.getline(temp,100);   
                 
            birthYear=atoi(temp);
            if (birthYear==0)    {
                cout << "Invalid valude..." << flush;
            }
        } while(birthYear==0);
       
       
    
           
        cout << "Your name is " << yourName
             << " and you are approximately "
             << (THISYEAR-birthYear)
             << " years old. " << endl;
       
        return 0;
    }
    5th
    Code:
    #include <string>
    #include <iostream>
    #include <sstream>       // for istringstream convert()
    using namespace std;
    
    int main()
    {
        const int THISYEAR = 2007;
        string yourName;
        int birthYear;
        string birth;               //για το έτος γέννησης
       
        cout << "What's your name ? " << flush;
        getline(cin,yourName);
        for(;1;)    {
                 cout << "What year were you born? ";
                 getline(cin,birth);
                 // μετατροπή string -----> int
                 istringstream convert(birth);
                 // τοποθέτηση στην int birthYear
                 convert >> birthYear;
                     // αν δεν πετύχει σημαίνει ότι δεν είναι αριθμός
                     if(!convert    {
                        cout << " This is not valid.Try again...." << endl;
                         continue;
                    } else {
                        break;
                    }
        }
       
        cout << "Your name is " << yourName
                 << " and you are approximately "
                 << (THISYEAR-birthYear)
                 << " years old. " << endl;
       
      
       
        return 0;
    }
    6th
    Code:
        #include <string>
        #include <iostream>
        #include <cstdlib>        //Για να κάνεις calls σε commands από το prompt π.χ. την PAUSE, επίσης έχει την atoi
        #pragma argsused
    
        //Ελέγχει εαν το string περιέχει αριθμό
        // εαν ναι επιστρέφει true
        // αλλιώς επιστρέφει false
        bool CheckStr(const std::string& s)
        {
           for (int i = 0; i < s.length(); i++) {
               if (!std::isdigit(s[i]))
        		   return false;
           }
           return true;
        }
    
        //Παίρνει το όνομα
        void GetName(std::string& yourName)
        {
        	using namespace std;
        	cout << "What's your name ? " << flush;
        	getline(cin, yourName);
        }
    
        //Παίρνει την ημ. γέννησης
        void GetBirthdate(std::string& birthYear)
        {
        	using namespace std;
        	cout << "What year were you born? ";
        	getline(cin, birthYear);
        }
    
        int main(int argc, char* argv[])
        {
        	using namespace std;
        	const int THISYEAR = 2007;
        	string yourName;
        	string birthYear;
        	int intYear;
        	bool exit = false;
    
        	//Μέχρι να δώσει σωστή ημ. ο χρήστης το πρόγραμμα κάνει loop
        	while (!exit)
        	{
        		GetName(yourName);			//Παίρνει το όνομα
        		GetBirthdate(birthYear);	//Παίρνει την ημ. γέννησης
    
    
        		if ( CheckStr(birthYear) ) { 	//Εάν η ημερομηνία είναι σωστή
        			  intYear = atoi(birthYear.c_str() ); 	//Μετατρέπει το string σε integer
        			  cout << "Your name is " << yourName
        				<< " and you are approximately "
        				<< (THISYEAR-intYear)
        				<< " years old. " << endl;
        				exit = true;
        		}
        		else {
        			  cerr << "This is not valid."
        				<< " Try again..." << endl;
        		}
        	}
    
        	system("PAUSE");
        	return 0;
        }
    Thanx for your time

  2. #2
    Registered User mikeman118's Avatar
    Join Date
    Aug 2007
    Posts
    183
    >>//Για να κάνεις calls σε commands από το prompt π.χ. την PAUSE, επίσης έχει την atoi
    >>//για το έτος γέννησης
    >>// αν δεν πετύχει σημαίνει ότι δεν είναι αριθμός

    What is all that? Are we supposed to be able to understand that? Is it just my browser, because that text looks very strange.

    Code:
    int main()	{
    	using namespace std;
    I'm pretty sure that that's not a good idea (you're supposed to put it the header). It may work but I doubt that it's a good idea.

    >>Which is the most suitable source code?
    I don't think that it really matters, as long as it works (I can't tell you which is better, however).
    Last edited by mikeman118; 11-25-2007 at 12:35 PM.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What is all that? Are we supposed to be able to understand that? Is it just my browser, because that text looks very strange.
    It is text in a language other than English, and I expect that it is part of this homework assignment that BlackSlash12 expects us to do for him/her.

    I'm pretty sure that that's not a good idea (you're supposed to put it the header). It may work buy I doubt that it's a good idea.
    It will work, and it is a far better idea than putting it in a header. You are not supposed to put using directives and declarations in a header, unless it happens to be within some class or function scope for some good reason.

    BlackSlash12, tell us what you think is the "most suitable source code", and why. We can then review your analysis. After all, without any context, I would say that none of them is suitable, because there were no requirements specified to begin with.
    Last edited by laserlight; 11-25-2007 at 12:16 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Not sure what happened to 4th (it went 3rd then 5th), but I'd go with 5th.

    But I would also add checks to the return result of each getline as well.

    The solutions which involve char arrays, and use of atoi() can't be recommended in a C++ program. atoi() for example cannot detect numeric overflow.

    Solutions which attempt input and conversion at the same time (eg. cin>>birthYear) involve a lot of messy cleanup when it goes wrong.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    Ok guys here it is the deal.

    I want to make a program that prints out your age. It asks for your name and for your date of birth. The BIG problem is that I want to check the birth variable. If you type 1989 then it's ok. But what if you type a character such as a instead of a number ?

    I found that there are two solutions.
    1)The first one is using direct input and checking the values like this way:

    Code:
    cout <<"What year were you born? " << flush;
    	while(!(cin>>birthYear))	//if the input stream has problems
    	{
    		cin.clear();	// cancel the fail state of the input sream
    		cin.ignore(numeric_limits<streamsize>::max(),'\n');  // thrash the garbage chars
    				
    		cout << "No valid value. ";
    		cout <<"What year were you born? " << flush;
    	}

    or the
    2) second solution is using a convertion of string to an integer using atoi() or istringstream convert().

    Which method is better ?


    PS: Sorry for the comments...it's Greek Language due to by cources.
    Thank you for your time!!!!!

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In general, both methods work the same and just as well.
    For which is more efficient, I can't say, but I don't believe there's a difference. My preffered method is the second solution.

  7. #7
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    If you choose the second method, then you have to create one extra string variable which means more RAM is needed.

    Just check out this:
    Code:
    #include <string>
    #include <iostream>
    #include <limits>
    
    #define THISYEAR 2007
    
    
    int main()	{
    
    	using namespace std;
    	string yourName;
    	int birthYear;
    	
    	cout << "What's your name ? " << flush;
    	cin >> yourName;
    	
    	cout << "What year were you born? ";
    	cin >> birthYear;
    
    	while(!cin.good() || birthYear <= 0 || birthYear >= THISYEAR)	{
    		cin.clear( );
    		cin.ignore( numeric_limits<streamsize>::max( ), '\n');
    		cout << "No Valid value. What year were you born? " << flush;
    		cin >> birthYear;
    	  }
    
    
    		
    	cout << "Your name is " << yourName
    		 << " and you are approximately "
    		 << (THISYEAR-birthYear)
    		 << " years old. " << endl;
    	
    	return 0;
    }
    Is this method ok ? Are you applied with that or there's something that I should fix it ?
    Thank You!!!!

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You just waited several seconds for the user to input about 10 bytes of data. Neither post-processing that data for a millisecond nor making a few copies of it has any visible performance or memory impact.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    I don't understand what you mean...

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I think what cornedbee is trying to say is that creating an extra copy of a string will not have any noticable impact in a piece of code like this - at least not if we are running on a modern PC or something like that. If you try to cram the entire program into a 4KB RAM on some embedded system, then yes, it will matter if you allocate some extra space. But not on a PC with hundreds (or thousands) of megabytes of RAM.

    It is of course good to be aware of how much memory you use in an application, and when/where you actually NEED to use this extra memory, and what can be avoided. But unless there's a specific PROBLEM with creating an extra copy of a single string, then there's really no reason to NOT have an extra string if it in other ways is useful.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    More succinctly, there were two people talking about efficiency in their answers. I just wanted to point out that this is a case where you really don't need to bother.

    By the way, portable C++ code should limit itself to a very basic character set, even in the comments. It may be a requirement from your course, but putting Greek letters in the comments is still a bad idea.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Registered User
    Join Date
    Aug 2007
    Posts
    66
    I am not asking for my course exercises. I am asking because I want to develop a Qt program on GNU/Linux (for Desktops). So, matsp you said that there is not problem using string conversion to integer, right ?

    Thank you guys

    PS: Sorry for the Greek comments.

    by the way I prefer using the method without conversion. Something like this:
    Code:
    #include <iostream>
    #include <limits>
    #include <string>
    using namespace std;
    
    
    void cin_fix_input(void)
    {
    	cin.clear();
    	cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    
    int main()
    {
    	using namespace std;
    
    	string firstName, lastName, city, job;
    	int age, phone;
    
    	cout << "What's your first name? " << flush;
    	cin >> firstName;
    
    	cout << "What's your last name? " << flush;
    	cin >> lastName;
    
    	cout << "What is your job? " << flush;
    	cin >> job;
    
    	cout << "Where do you live? (city)  " << flush;
    	cin >> city;
    
    	cout << "What year were you born? " << flush;
    	cin >> age;
    
    	while(!cin.good() || age<=1900 || age>=2007)
    	{
    		cin_fix_input();
    		cout << "No valid age.... What year were you born? " << flush;
    		cin >> age;
    	}
    
    	cout << "What is your phone number? " << flush;
    	cin >> phone;
    
    	while(!cin.good() || phone<=0)
    	{
    		cin_fix_input();
    		cout << "No valid number.... What is your phone number? " << flush;
    		cin >> phone;
    	}
    
    	cout <<"OTE Telephone Company"
    		 <<"\nOk.Registered.... ===>"
    		 <<"First Name ==========================> " << firstName << endl
    		 <<"Last  Name ==========================> " << lastName << endl
    		 <<" Location  ==========================> " << city << endl
    		 <<" Work as   ==========================> " << job << endl
    		 <<"   Age     ==========================> " << (2007-age) << endl
    		 <<"  phone    ==========================> " << phone << endl;
    	return 0;
    }
    More speed, less RAM. Great!
    Last edited by BlackSlash12; 11-26-2007 at 09:48 AM.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by BlackSlash12 View Post
    I am not asking for my course exercises. I am asking because I want to develop a Qt program on GNU/Linux (for Desktops). So, matsp you said that there is not problem using string conversion to integer, right ?

    Thank you guys
    It would only be a problem if you have VERY little memory. Using a string to convert to integer would perhaps use 20-50 bytes more memory - nothing you'd worry about on a regular PC.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Don't use flush unless necessary. Output is buffered for a reason.
    Your code is also very error prone. If a user enters a string instead of an integer, the rest of the cins will fail.

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I'd just like to reiterate my comment that attempting input AND conversion at the same time is just a mess waiting to happen, as already noted by several others.

    By having a consistent approach which always works, you cut down on all the surprises later on in the code.

    As for your concerns over efficiency, then consider this:
    "It is easier to make a working program efficient than it is to make an efficient program work".
    In other words, make it right first, then worry about trying to make it smaller / faster.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. entering numbers to array in a row whithout length input
    By transgalactic2 in forum C Programming
    Replies: 55
    Last Post: 01-02-2009, 04:02 AM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Problem getting the input from a temp variable into the Array
    By hello_moto in forum C++ Programming
    Replies: 3
    Last Post: 03-16-2006, 01:50 AM
  4. String input problem, gets
    By willc0de4food in forum C Programming
    Replies: 13
    Last Post: 03-05-2005, 02:05 PM
  5. Problem with Printing message
    By robert_sun in forum C Programming
    Replies: 2
    Last Post: 05-16-2004, 02:09 PM