input tests

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

39 Replies - 1302 Views - Last Post: 05 May 2013 - 09:26 PM Rate Topic: -----

#16 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 04 May 2013 - 09:49 AM

im sorry i cant find that Compiler Flags check boxes u are talking about :(

i press Project but the build options aint availble to me...

and i will use your method i think its better not to mess with floating numbers i always hated them they are troublmakers
thank u :)
Was This Post Helpful? 0
  • +
  • -

#17 jimblumberg  Icon User is online

  • member icon


Reputation: 3987
  • View blog
  • Posts: 12,298
  • Joined: 25-December 09

Re: input tests

Posted 04 May 2013 - 10:31 AM

I said right click on your open project in the Projects window, did you do this?


Attached Image



Jim
Was This Post Helpful? 1
  • +
  • -

#18 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 04 May 2013 - 10:47 AM

i dont have such a thing look:

Attached image(s)

  • Attached Image

Was This Post Helpful? 0
  • +
  • -

#19 jimblumberg  Icon User is online

  • member icon


Reputation: 3987
  • View blog
  • Posts: 12,298
  • Joined: 25-December 09

Re: input tests

Posted 04 May 2013 - 10:57 AM

That's because you failed to create a project. Trying to compile individual files without a project is not recommended.

See this link: Creating a new project.

Jim
Was This Post Helpful? 1
  • +
  • -

#20 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 04 May 2013 - 11:02 AM

oh i understand now... thats what they want in this course just creating files not a whole project
thanks again
Was This Post Helpful? 0
  • +
  • -

#21 jimblumberg  Icon User is online

  • member icon


Reputation: 3987
  • View blog
  • Posts: 12,298
  • Joined: 25-December 09

Re: input tests

Posted 04 May 2013 - 11:09 AM

Don't just create the files, create the project then add the files to the project. If you're not going to use the project then you should compile your files at the command line so you can force the compiler to help you by emitting warnings.

Jim
Was This Post Helpful? 1
  • +
  • -

#22 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 04 May 2013 - 11:31 AM

ok done :)
Was This Post Helpful? 1
  • +
  • -

#23 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3450
  • View blog
  • Posts: 10,646
  • Joined: 05-May 12

Re: input tests

Posted 04 May 2013 - 02:02 PM

View PostMaria23, on 04 May 2013 - 11:05 AM, said:

give me an example for a number that wont work on that code cuz i cant find one.. this is my code now:
int input()
{
    int res;
    double num;
    printf("Enter a positive integer number: ");
    res=scanf("%lf",&num);
    if(res<1)
    {
        printf("Error!");
        exit(1);
    }

    while((num!=(int)num)||(num<=0))
    {
        printf("illegal input, please enter a positive integer number: ");
        res=scanf("%lf",&num);
        if(res<1)
        {
        printf("Error!");
        exit(1);
        }

    }
  return num;
}





I accept your challenge. Here, try this positive integer:

4294967295
Was This Post Helpful? 1
  • +
  • -

#24 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 04 May 2013 - 09:54 PM

actully it wasnt a chalange... i really didnt find a number ;)
thanks that number doesnt work i understand very well now i changed my code i no longer use that comparing with floating numbers :)
thnx again
Was This Post Helpful? 1
  • +
  • -

#25 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 05 May 2013 - 08:47 AM

View Postjimblumberg, on 04 May 2013 - 11:09 AM, said:


hi Jim,
in the previous question... can i do something like this instead of using string:
im not going to write the whole code i dont have the CodeBlocks here and the idea just came... it goes like this:

receiving the number as floating number then convert it to integer number then check if the floaing number - the integer part >0:


double num, res;
int num2;
num2= (int)num;
res= num-num2;
if(res>0)
/* ask for a new input */ 



would this work or it still floating numbers comparing?

This post has been edited by Maria23: 05 May 2013 - 08:49 AM

Was This Post Helpful? 0
  • +
  • -

#26 jimblumberg  Icon User is online

  • member icon


Reputation: 3987
  • View blog
  • Posts: 12,298
  • Joined: 25-December 09

Re: input tests

Posted 05 May 2013 - 09:56 AM

Trying to convert a floating point number to any of the integral types can result in numeric overflow. And when dealing with a signed integral number this overflow leads to undefined behavior.

If you need to be able to determine if a user enters a floating point value instead of an integer you should accept the user input into a string, validate the input, then convert the input to the proper type.

In C++ the conversion is the easiest part of this procedure, use a stringstream and the insertion operator to convert the number to the proper type. The validation, is much more involved. First you need to test to insure your string only contains digits, and the sign characters. Then you need to insure that the length of your sting is small enough to be held in a integral type, and finally insure that the string won't overflow your int.

So as you can see handling user input can become quite complicated. Unless you have been specifically told to reject floating point numbers and ask for re-entry I would just accept the integral portion of the number as your int, then ignore() the rest of the data in the buffer.

Jim
Was This Post Helpful? 1
  • +
  • -

#27 Maria23  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 24-November 12

Re: input tests

Posted 05 May 2013 - 11:15 AM

yes i didnt think it will be that complicated... i guess i will use that string method after.. i tried to find something less complicated than that...
thanks for ur replies
Was This Post Helpful? 0
  • +
  • -

#28 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 275
  • View blog
  • Posts: 1,778
  • Joined: 20-September 08

Re: input tests

Posted 05 May 2013 - 02:55 PM

View PostMaria23, on 05 May 2013 - 02:15 PM, said:

yes i didnt think it will be that complicated... i guess i will use that string method after.. i tried to find something less complicated than that...
thanks for ur replies


Validating input can be fun ... :)

In Python and HLA, if numeric input overflows its container type, it will throw an exception, which you can then handle

In C and C++, many times you can just use the error flags set by scanf or cin

In C ...
int numGood = scanf( "%d", &intVal );
if( numGood == 1 ) accept( intVal ); else notAccept( intVal );

in C++ ...
if( cin >> intVal ) accept( intVal ); else notAccept( intVal );

You may like to see the example(s) below designed to help students who are beginning C or C++ with their user input validation(s) ...


Six Fast Steps to Programming in C


/* getValidInt.c  */ /* revised 2013-05-05 */

/* http://developers-heaven.net/forum/index.php/topic,46.0.html */

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* re. strlen, strcpy, strchr... */
#include <ctype.h> /* re, tolower... */
#include <math.h> /* re. log10 ... */

#define BIG_BUF_LEN 1024

/* presumming ? negative numbers are stored in memory using 2's complement ? */
#define MIN_INT  ( 1 << ( sizeof( int ) * 8 - 1 ) )
#define MAX_INT -( MIN_INT + 1 )

#define NUM_DIG_INT ( (int) log10( MAX_INT ) + 1 )


char* fixFgets( char* str )
{
    char* p = strchr( str, '\n' );
    if( p )
        *p = 0; /* strip off '\n' char if present */
    else
        while( getchar() != '\n' ); /* flush stdin to end of line */
    return str;
}

/* since using 'static' buf inside, memory persists ... so can return address */
char* getString( const char* msg, unsigned max_len )
{
    static char buf[BIG_BUF_LEN];
    for( ; ; )
    {
        fputs( msg, stdout ); fflush( stdout );
        fgets( buf, BIG_BUF_LEN, stdin );

        fixFgets( buf );

        if( buf[0] && strlen( buf ) <= max_len ) break;
        else if( !buf[0] ) printf( "\nBlank line NOT valid here ... \n" );
        else printf( "\nMax len of %u char's was exceeded ... \n", max_len );
    }
    return buf;
}

int getChar( const char* msg )
{
    int reply;
    fputs( msg, stdout ); fflush( stdout );
    reply = getchar();
    if( reply != '\n' )
        while( getchar() != '\n' ) ; /* 'flush' stdin buffer */
    return reply;
}

int more() /* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered */
{
    if( tolower( getChar( "More (y/n) ? " )) == 'n' ) return 0;
    /* else ... */
    return 1;
}

/* simple ... but accepts and returns input like 3.3 ... as (int) 3 ... */
int getValidInt( const char* prompt )
{
    for( ; ; ) /* an example of a C/C++ forever loop ... until 'return' */
    {
        int numGood, testInt;
        fputs( prompt, stdout ); fflush( stdout );
        numGood = fscanf( stdin, "%d", &testInt );
        while( getchar() != '\n' ); /* 'flush' stdin ... as we go ... */
        if( numGood == 1 ) return testInt;
        /*else ...*/
        puts( "Invalid input! Integers only please ..." );
    }
}

/* accepts only positive (i.e. >= 0) valid int range of values ... */
int getValidPosInt( const char* prompt, int high )
{
    for( ; ; ) /* an example of a C/C++ forever loop ... until 'return' */
    {
        char* tmp = getString( prompt, NUM_DIG_INT );
        int i = strlen( tmp );
        int good = 1;
        while( --i >= 0 && good )
        {
            if( !isdigit( tmp[i] ) ) good = 0;
        }

        if( good )
        {
            int t = atoi( tmp );
            if( t >= 0 && t <= high ) /* will 'under flow' i.e. be negative
                                         if t too big */
                return t;
        }
        /*else ...*/
        printf( "\nInvalid input! Integers please, only in range %d..%d\n",
                0, high );
    }
}

/*  returns a valid int in range (MIN_INT+1)..MAX_INT  */
int getValidInt2( const char* prompt, int low, int high )
{
    for( ; ; ) /* an example of a C/C++ forever loop ... until 'return' */
    {
        int good = 1, i, sign = 1;
        char* tmp = getString( prompt, NUM_DIG_INT+1 ); /* leave room for + - */

        if( tmp[0] == '+' ) ++tmp;
        else if( tmp[0] == '-') { ++tmp; sign = -1; }


        i = strlen( tmp );
        while( --i >= 0 && good )
        {
            if( !isdigit( tmp[i] ) ) good = 0;
        }

        if( good )
        {
            int t = atoi( tmp );
            if( t >= 0 && t <= high )
                if( low <= sign*t )
                    return sign*t;
        }
        /*else ...*/
        printf( "\nInvalid input! Integers please, only in range %d..%d\n",
                low, high );
    }
}





int main()
{
    int count = 0;
    double sum = 0;

    printf( "Number of digits in an int is %d\n", NUM_DIG_INT );
    printf( "\nMIN_INT = %d, MAX_INT  = %d\n\n", MIN_INT, MAX_INT );


    do
    {
        int testInt = getValidInt2( "Enter next integer to sum: ",
                                    MIN_INT + 1, MAX_INT );
        ++ count;
        sum += testInt;
    }
    while( more() ); /* make sure stdin is 'empty' before calling 'more()' */

    printf( "\nFor %d numbers entered, sum was %.0f and average was %.2f\n",
    count, sum, sum/count );


    /* keep 'Window' open until 'Enter' key is pressed ... */
    getChar( "\nPress 'Enter' to continue/exit ... " );
    return 0;
}

This post has been edited by David W: 05 May 2013 - 03:02 PM

Was This Post Helpful? 0
  • +
  • -

#29 jimblumberg  Icon User is online

  • member icon


Reputation: 3987
  • View blog
  • Posts: 12,298
  • Joined: 25-December 09

Re: input tests

Posted 05 May 2013 - 03:11 PM

Here's an example of validation using C++:

include <iostream>
#include <sstream>
#include <string>
#include <limits>

bool validate(const std::string& entry, int& number);

int main()
{
   std::string entry;
   std::cout << "Please enter a number: ";
   getline(std::cin, entry);
   int number;
   if(validate(entry, number))
      std::cout << number << std::endl;
   else
      std::cout << "Invalid entry!" << std::endl;

   return(0);
}

bool validate(const std::string& entry, int& number)
{
   // Insure only digits in the string.
   std::string::size_type idx = entry.find_first_not_of("0123456789+-");
   if(idx != std::string::npos)
      return(false); // contains characters that aren't numbers.
   if(static_cast<int>(entry.size()) > std::numeric_limits<int>::digits)
      return(false); // Too many digits for an integral type.
   long long temp;
   std::istringstream ins(entry);
   ins >> temp;
   if(!ins)
      return(false); // Error in conversion.
   if(temp > std::numeric_limits<int>::max())
      return(false); // Bigger than an int.
   // Everything passed so can now convert temp to an int.
   number = static_cast<int>(temp);
   return(true);
}



Jim
Was This Post Helpful? 1
  • +
  • -

#30 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 275
  • View blog
  • Posts: 1,778
  • Joined: 20-September 08

Re: input tests

Posted 05 May 2013 - 05:40 PM

View Postjimblumberg, on 05 May 2013 - 06:11 PM, said:

Here's an example of validation using C++:

include <iostream>
#include <sstream>
#include <string>
#include <limits>

bool validate(const std::string& entry, int& number);

int main()
{
   std::string entry;
   std::cout << "Please enter a number: ";
   getline(std::cin, entry);
   int number;
   if(validate(entry, number))
      std::cout << number << std::endl;
   else
      std::cout << "Invalid entry!" << std::endl;

   return(0);
}

bool validate(const std::string& entry, int& number)
{
   // Insure only digits in the string.
   std::string::size_type idx = entry.find_first_not_of("0123456789+-");
   if(idx != std::string::npos)
      return(false); // contains characters that aren't numbers.
   if(static_cast<int>(entry.size()) > std::numeric_limits<int>::digits)
      return(false); // Too many digits for an integral type.
   long long temp;
   std::istringstream ins(entry);
   ins >> temp;
   if(!ins)
      return(false); // Error in conversion.
   if(temp > std::numeric_limits<int>::max())
      return(false); // Bigger than an int.
   // Everything passed so can now convert temp to an int.
   number = static_cast<int>(temp);
   return(true);
}



Jim



Nice example Jim ...

However ...

I think you may have ... (intentionally perhaps) ...

overlooked the case of multiple '+' or '-' char's

or these char's occurring NOT as the leading char before any digits

This, however, does serve to demonstrate that validation of user input is no trivial matter!

But this is where the fun comes in ...

Trying to imagine ALL the possible user input ...

that the program design spec's wish to have called ...

'Not Valid Input Here ... '

Take a look at the slight revision below to Jim's code ...

and if anyone can see further need to include some further test for 'bad int type' user input ...

please upgrade this post.


#include <iostream>
#include <sstream>
#include <string>
#include <limits>
#include <cmath>

/* presumming ? negative numbers are stored in memory using 2's complement ? */
#define MIN_INT  ( 1 << ( sizeof( int ) * 8 - 1 ) )
#define MAX_INT -( MIN_INT + 1 )

#define NUM_DIG_INT ( (int) log10( MAX_INT ) + 1 )


bool validate( const std::string& entry, int& number, std::string& errMsg );


int main()
{
    int count = 0, number = 0;
    do
    {
        ++ count;
        std::cout << count << ". Please enter a number (0 to exit) : ";
        std::cout << std::flush;

        std::string entry, err;
        getline(std::cin, entry);
        number = -1;
        if( validate( entry, number, err ) )
            std::cout << "\nYou entered : " << number << std::endl;
        else
        {
            --count;
            std::cout << "\nInvalid entry!\n" << err << std::endl;
        }

        std::cout << std::endl;
            
    }
    while( number );
}

bool validate(const std::string& entry, int& number, std::string& errMsg )
{
    errMsg.clear();
    bool hasSign  = false;

    // first check only one + - sign AND that it is at front
    std::string::size_type idx = entry.find_last_of( "+-" );
    if( idx != std::string::npos ) // then has a  sign
    {
        hasSign = true;
        if( idx != 0 ) // is sign at front ?
        {
            errMsg += "+/- sign error(s)!  ";
            return false;
        }

        // ok sign was at front ...
        if( entry.size() < 2 )
        {
            errMsg += "A joker ...eh!  NO digits follow the sign.  ";
            return false;
        }
    }


    // Insure only digits in the string.
    idx = entry.find_first_not_of( "0123456789+-" );
    if( idx != std::string::npos )
    {
        errMsg += "Invalid Char's Present!  ";
        return false ;
    }

    if( static_cast< int >( entry.size() )  > NUM_DIG_INT + hasSign )
    {
        errMsg += "Too many digits!  ";
        return false ; // Too many digits for an integral type.
    }


    long long temp;

    std::istringstream ins( entry );
    if( ins >> temp )
    {
        // Bigger than an int.
        if( temp  >  std::numeric_limits< int >::max() )
        {
            errMsg += "Overflow Error!  ";
            return false;
        }
        else if( temp  <  std::numeric_limits< int >::min() )
        {
            errMsg += "Underflow Error!  ";
            return false;
        }
        // else ...
        // Everything passed so can now convert temp to an int.

        number = static_cast< int >( temp );
        return true ;
    }
    else
    {
        errMsg += "Conversion Error!  ";
    } 
    return false;
}



Like I said ... 'Not trivial' !

Already have made FOUR fixes/edits (3rd THANKS to 'SkyDiver', 4th THANKS to 'Jim'),

to what I first posted :)

Now a 5th and 6th revision to eliminate the 'defines' used above ... and to eliminate a block of redundant code ... and also to use some cleaner matching of unsigned type with unsigned types ...

#include <iostream>
#include <sstream>
#include <string>
#include <limits>
#include <cmath>


unsigned numDigits( int num )
{
    return  static_cast< unsigned > (log10( abs(num) )) + 1;
}

bool validate( const std::string& entry, int& number, std::string& errMsg );



int main()
{
    int count = 0, number = 0;
    do
    {
        ++ count;
        std::cout << count << ". Please enter a number (0 to exit) : ";

        // I make this a habit to guard against those rare times ...
        // when I was expecting output, but had none ... until later ...
        // and sometimes not till after something else was printed at first.
        std::cout << std::flush; 

        std::string entry,
                    err;
        getline( std::cin, entry );
        number = -1;
        if( validate( entry, number, err ) )
            std::cout << "\nYou entered : " << number << std::endl;
        else
        {
            --count;
            std::cout << std::endl << err << std::endl;
        }

        std::cout << std::endl;
            
    }
    while( number );
}



bool validate( const std::string& entry, int& number, std::string& errMsg )
{
    errMsg.clear();
    bool hasSign  = false;

    // first check if only one + or - sign ...
    // AND ... that it is at the front
    std::string::size_type pos = entry.find_last_of( "+-" );

    if( pos != std::string::npos ) // then has a  sign
    {
        hasSign = true;
        if( pos != 0 ) // then sign is NOT at front ... so ...
        {
            errMsg += "+/- sign error(s)!  ";
            return false;
        }
    }

    // compare length of input string to max num of char's allowed in an int ...
    // allowing one extra char if there was a leading + or - sign
    if( entry.size() > numDigits( std::numeric_limits< int >::max() ) + hasSign )
    {
        errMsg += "Too many digits!  ";
        return false ; // Too many digits for an int
    }

    // now test if only digits in input string
    pos = entry.find_first_not_of( "0123456789+-" );
    if( pos != std::string::npos )
    {
        errMsg += "Invalid char's present!  ";
        return false ;
    }


    long long temp;

    std::istringstream ins( entry );
    if( ins >> temp )
    {
        if( temp  >  std::numeric_limits< int >::max() )
        {
            errMsg += "Overflow error!  ";
            return false;
        }

        if( temp  <  std::numeric_limits< int >::min() )
        {
            errMsg += "Underflow error!  ";
            return false;
        }

        // if reach here
        // Everything passed so can now convert temp to an int.

        number = static_cast< int >( temp );
        return true ;
    }

    // else

    errMsg += "Conversion error!  ";
    return false;
}


This post has been edited by David W: 06 May 2013 - 06:05 AM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3