C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old December 1st, 2012, 10:50 AM
so.very.tired so.very.tired is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 112 so.very.tired User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 12 m 48 sec
Reputation Power: 1
Help with a function

i wrote a function that checks if the user typed in a valid integer number.
the function works perfectly, but there's a little problem:

whenever the user enters an invalid input (any non digit character) - the function returns the value 0.
and if the input is valid (i.e a number - any number) - the function returns it to the main program.
the problem is - 0 is a valid number, so if the user enters 0 or he enters a wrong input - either way - the function will return 0, so the main program can't tell between these two scenarios.
is there a way to overcome this situation?

Thanks and have a nice weekend!

Reply With Quote
  #2  
Old December 1st, 2012, 11:57 AM
MrFujin's Avatar
MrFujin MrFujin is offline
Lord of the Dance
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Oct 2003
Posts: 3,129 MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level)MrFujin User rank is General 11st Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 22 h 45 m 33 sec
Reputation Power: 1736
Please post the code for your function.

Will negative number be valid as well? if no, you could return -1 for invalid number format.

If the function should only check if number is valid, it would be enough to return true (1) or false (0).

Reply With Quote
  #3  
Old December 1st, 2012, 12:19 PM
Lux Perpetua Lux Perpetua is offline
Contributing User
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Feb 2004
Location: San Francisco Bay
Posts: 1,936 Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 2 h 12 m 42 sec
Reputation Power: 1312
The standard library function strtol shows one way of overcoming this limitation: give the caller a pointer to the end of the valid input. Then the caller can check whether it coincides with the end of the string (for example, if the whole string was supposed to represent an integer).

Reply With Quote
  #4  
Old December 1st, 2012, 12:27 PM
so.very.tired so.very.tired is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 112 so.very.tired User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 12 m 48 sec
Reputation Power: 1
Hi MrFujin.

thanks for the help.

yes, negative number is valid as well.

here's the code:


Code:
int InputCheck()
{

  char c;
  int num1=0, num2=0, i=1, minus=0;

   do
   {
    c=getchar();
    if ((c=='-')&&(i==1))  //checks if first char is minus - i.e if number is negative
      minus=1;
    if (isdigit(c))  //checks if char is a digit
     {
      num1+=(c-'0')*i;   //saves the digit as integer
      i*=10;
     }
    else if ((c!='\n')&&(c=='-')&&(i!=1))  //if char isn't a digit
      return 0;
   }while (c!='\n');

   for ( i/=10 ; i>=1 ; i/=10,num1/=10 )  //loop to flip the number backwards
      num2+=(num1%10)*i;
   return minus==1 ? -num2 : num2 ;
}

Reply With Quote
  #5  
Old December 1st, 2012, 12:31 PM
so.very.tired so.very.tired is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 112 so.very.tired User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 12 m 48 sec
Reputation Power: 1
Hi Lux Perpetua.
im not allowed to use arrays, or anything outside the stdio.h library.

Reply With Quote
  #6  
Old December 1st, 2012, 01:18 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,357 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 9 h 9 m 51 sec
Reputation Power: 383
ctypes.h declares isdigit . (Your instructions wouldn't prevent me from using isdigit.)

/*
* InputCheck returns status 0 if the
* result is valid, otherwise returns 1.
*/

int InputCheck(int *result);


I'd also write

int minus=1;
...
*result = minus*num2;

I've reduced the code complexity. It's simpler because there are fewer paths through the function.
__________________
[code]Code tags[/code] are essential for python code!

Last edited by b49P23TIvg : December 1st, 2012 at 01:20 PM.

Reply With Quote
  #7  
Old December 1st, 2012, 01:36 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,127 dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 3 Days 18 h 16 sec
Reputation Power: 1949
as you were

Last edited by dwise1_aol : December 1st, 2012 at 01:40 PM.

Reply With Quote
  #8  
Old December 1st, 2012, 01:43 PM
so.very.tired so.very.tired is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 112 so.very.tired User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 12 m 48 sec
Reputation Power: 1
Hi b49P23TIvg.
thanks for the great help.

sorry for not pointing that out earlier: i'm not allowed to use pointers either (nor recursion)...

Reply With Quote
  #9  
Old December 1st, 2012, 02:04 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,357 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 9 h 9 m 51 sec
Reputation Power: 383
I think c allows a function to return a structure. I've never explicitly written such code, but if you can then you could return 2 variables at once.

Another option: save the success as a static variable. Since we love encapsulation,
Code:
int InputCheck(int mode) {
  static int successful;
  if (mode) {
    int temp = successful;
    successful = 0;
    return temp;
  }
  /* continue with rest of function */
  /* make sure to set successful to 1 if the data was ok */

Are you quite sure you understand your assignment? Professional footballers aren't required to bind their legs in burlap sacks.

Anyway, then you'd call InputCheck(0); to get an int, and InputCheck(1); to see if the value was valid. This is ridiculous.

Last edited by b49P23TIvg : December 1st, 2012 at 02:16 PM.

Reply With Quote
  #10  
Old December 1st, 2012, 02:30 PM
so.very.tired so.very.tired is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 112 so.very.tired User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 12 m 48 sec
Reputation Power: 1
Quote:
Originally Posted by b49P23TIvg
Are you quite sure you understand your assignment? Professional footballers aren't required to bind their legs in burlap sacks.


i couldn't agree more.
the idea to define a function to check the input was mine.
the assignment is to write a program that obtain as input an integer number, and prints the fibonacci sequence up to the number given.
for example, if the input is 9, the output should be:
0 1 1 2 3 5 8
if the input is -7, the output is an empty line.

but that's the easy part.
the real pain is that for any input that isn't a valid number, the program should print: "Wrong input!"

Reply With Quote
  #11  
Old December 1st, 2012, 03:01 PM
clifford's Avatar
clifford clifford is offline
Contributing User
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Aug 2003
Location: UK
Posts: 4,807 clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 2 Days 17 h 20 m 11 sec
Reputation Power: 1800
Use the return value purely as a validity flag, and return the input value via a pointer argument that points to a caller variable.

Code:
int inputInteger( int* answer )
{
  
    // Get and validate input...
    ....

    // If input OK, assign it to caller's variable
    if( input_valid )
    {
        *answer = value ;
    }

    // Return validity flag
    return input_valid ;
}


Where input_valid is zero for invalid and non-zero for valid. Then this is called thus (for example):
Code:
int value ;
valid = inputInteger( &value ) ;
if( valid )
{
    // value has input
}


Since you did not specify I have assumed that you are using C code and lower-common denominator C89; i.e. no built-in boolean and no reference types. C99 and C++ have features that could improve this code a little.

An alternative is to return a structure that has a validity flag and a value, but that is not really the most appropriate solution in this case.

Reply With Quote
  #12  
Old December 1st, 2012, 03:03 PM
clifford's Avatar
clifford clifford is offline
Contributing User
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Aug 2003
Location: UK
Posts: 4,807 clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level)clifford User rank is General 12nd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 2 Days 17 h 20 m 11 sec
Reputation Power: 1800
Quote:
Originally Posted by b49P23TIvg
Another option: save the success as a static variable.
But we might love reentrancy more!

Reply With Quote
  #13  
Old December 1st, 2012, 03:22 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,127 dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 14th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 3 Days 18 h 16 sec
Reputation Power: 1949
Here's a thought: what are the chances of the user entering the greatest magnitude negative number? Highly unlikely, so why not use that value to indicate wrong input?

limits.h contains macros that define the limits of values for the various datatypes; eg:
Code:
/*
 * Maximum and minimum values for ints.
 */
#define INT_MAX		2147483647
#define INT_MIN		(-INT_MAX-1)

#define UINT_MAX	0xffffffff

You could use either INT_MAX or INT_MIN, both highly unlikely input values. The main point in choosing a value to indicate an invalid value is that it be one that should not otherwise appear.

Another thought is that the stricture against pointers should not apply to using them in the parameter list of your function, which is not part of the assignment description. Most programming assignments are designed to have you practice what you have learned in class or in your reading assignments and that is why they will often restrict you from using a different technique. Since your assignment is apparently not supposed to be about other methods for returning certain information from a function, you should be free to use a pointer to return the input value via a pointer and the status as the return value, or vice-versa, especially if you annotate what you are doing and why in your comments and you do not use pointers elsewhere, thus demonstrating that you are conforming to the spirit of the assignment. Discussing this point with your instructor might also help; as I learned early on in military bureaucracy, rules are made to address a specific problem, but can have consequences unforeseen by the writers of those rules -- the same seems to apply to laws. If your problem is an unforeseen consequence of his restrictions, your instructor may give you permission to use a pointer in this one case. If unable to speak with him in order to obtain permission, then there's always the old adage: "Forgiveness is always easier to obtain than permission."
Comments on this post
Lux Perpetua agrees!

Reply With Quote
  #14  
Old December 1st, 2012, 07:54 PM
Lux Perpetua Lux Perpetua is offline
Contributing User
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Feb 2004
Location: San Francisco Bay
Posts: 1,936 Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level)Lux Perpetua User rank is General 5th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 2 h 12 m 42 sec
Reputation Power: 1312
Quote:
Originally Posted by dwise1_aol
Here's a thought: what are the chances of the user entering the greatest magnitude negative number? Highly unlikely, so why not use that value to indicate wrong input?
This is a really great answer. Integers that are close to the limits of the data type are likely to cause overflow under subsequent manipulation, anyway, so it's hardly a huge loss to sacrifice INT_MIN as an error indicator. Moreover, two's-complement integers already have one more negative value than positive values, and INT_MIN specifically is pathological (for example, -INT_MIN == INT_MIN (the negative of the most negative integer is negative!)), but removing INT_MIN makes everything symmetric.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Help with a function

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap