Command Line Arguement, can't get it to read in an int

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Apr 2008
Posts: 21
Reputation: MaestroRage is an unknown quantity at this point 
Solved Threads: 0
MaestroRage MaestroRage is offline Offline
Newbie Poster

Command Line Arguement, can't get it to read in an int

 
0
  #1
Apr 7th, 2008
I am trying to get the main to read in a number, and use that number to do a mod calculation. However my best efforts are giving me garbage values. I am sure I am not using the pointer correctly, yet my efforts have gone unrewarded. How can I get this program to take in a number and see if it divisible by 5?

  1. #include <stdio.h>
  2. #define POPPRICE 50 /*what the pop price is in cents*/
  3.  
  4. char c;
  5. int leftover=POPPRICE; //
  6. int value; // what was entered
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10. value=(int)argv[1];
  11. if ((value / 5) != 10)
  12. {
  13. printf("Please enter a number of multiples of 5\n");
  14. printf("%d\n",value);
  15. }
  16. else
  17. {
  18. printf("The price of pop is %d, cents", POPPRICE);
  19. printf("Please insert any combination of nickels [N or n],\n");
  20. printf("dimes [D or d] or quarters [Q or q].\n");
  21. printf("You can also return your money to you by pressing R or r\n");
  22. while ((c=getchar())!='e' && (c=getchar())!='E')
  23. {
  24. printf("We have not yet exited\n");
  25. scanf("%d",&value);
  26. }
  27. }
  28.  
  29. }
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 2,045
Reputation: Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of 
Solved Threads: 178
Aia's Avatar
Aia Aia is offline Offline
Postaholic

Re: Command Line Arguement, can't get it to read in an int

 
0
  #2
Apr 7th, 2008
value=(int)argv[1];
That will not give you what you want.
argv[1] is a string in the best case.

Validate that the user entered an argument at the command line. Then use sscanf() to read that string into an int previously declared.
  1. if ( sscanf( argv[1], "%d", &integer ) == 1 )
  2. {
  3. printf( "%d\n", integer );
  4. }
Last edited by Aia; Apr 7th, 2008 at 10:14 pm.
"If it moves, tax it. If it keeps moving, regulate it, and if it stops moving, subsidize it" - Ronald Reagan
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,829
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 750
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Senior Bitch

Re: Command Line Arguement, can't get it to read in an int

 
0
  #3
Apr 8th, 2008
>Then use sscanf() to read that string into an int previously declared.
If you're already validating the string, sscanf is overkill. If it's a valid integer you can use atoi safely. Or better yet, you can combine the conversion and the validation with strtol:
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. int main ( int argc, char *argv[] )
  6. {
  7. if ( argc > 1 ) {
  8. long value;
  9. char *end;
  10.  
  11. errno = 0;
  12. value = strtol ( argv[1], &end, 0 );
  13.  
  14. if ( *end == '\0' && errno == 0 )
  15. printf ( "Good integer: %ld\n", value );
  16. else
  17. fputs ( "Invalid integer format\n", stderr );
  18. }
  19.  
  20. return 0;
  21. }
New members chased away this month: 3
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 2,045
Reputation: Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of 
Solved Threads: 178
Aia's Avatar
Aia Aia is offline Offline
Postaholic

Re: Command Line Arguement, can't get it to read in an int

 
0
  #4
Apr 8th, 2008
>If you're already validating the string, sscanf is overkill.
Would you mind to elaborate in what way this would be overkill?

  1. #include <stdio.h>
  2.  
  3. int main ( int argc, char *argv[] ) {
  4. int integer = 0;
  5.  
  6. if ( argc > 1 ) {
  7. if ( sscanf( argv[1], "%d", &integer ) == 1 ) {
  8. <snip>
  9. }
  10. else {
  11. <snip>
  12. }
  13. }
  14. <snip>
  15. return 0;
  16. }
Last edited by Aia; Apr 8th, 2008 at 6:23 pm.
"If it moves, tax it. If it keeps moving, regulate it, and if it stops moving, subsidize it" - Ronald Reagan
Reply With Quote Quick reply to this message  
Join Date: Feb 2008
Posts: 1,669
Reputation: jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of 
Solved Threads: 123
jephthah's Avatar
jephthah jephthah is offline Offline
Posting Virtuoso

Re: Command Line Arguement, can't get it to read in an int

 
0
  #5
Apr 9th, 2008
here's the simple answer:

  1. int main (int argc, char *argv[])
  2. {
  3. int value;
  4.  
  5. value = atoi(argv[1]);
  6.  
  7. ...
  8.  
  9. }

of course that doesn't even begin to address error checking. But that wasn't your question, so I'm leaving it that out in favor of the simple answer as to why your code didnt work (because you cant merely cast a string as an int)

now, lets the fight resume. i got 3:1 on narue. she wields a wicked chainsaw. i still have scars.


.
Last edited by jephthah; Apr 9th, 2008 at 3:53 am.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,829
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 750
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Senior Bitch

Re: Command Line Arguement, can't get it to read in an int

 
2
  #6
Apr 9th, 2008
>Would you mind to elaborate in what way this would be overkill?
Gladly. I misread your post.

>here's the simple answer:
In this case I'd say that simplicity isn't worth it. You're teaching bad habits again.

>of course that doesn't even begin to address error checking.
Indeed. You make several assumptions about your data:

1) You assume that argv[1] exists.
2) You assume that argv[1] is not a null pointer.
3) You assume that argv[1] represents a valid integer.

Simple or not, those assumptions make your code severely broken because you simply can't control the data sent to your program from an outside source. At the very least you need to correct those three things:
  1. int main ( int argc, char *argv[] )
  2. {
  3. /* Make sure argv[1] exists and is not null */
  4. if ( argc > 1 ) {
  5. /* Make sure argv[1] is a valid integer */
  6. if ( try_parse_int ( argv[1] ) ) {
  7. int value = atoi ( argv[1] );
  8.  
  9. /* ... */
  10. }
  11. }
  12.  
  13. return 0;
  14. }
The problem with atoi is that it's literally impossible to error check it. The return value is the only guaranteed mechanism for determining an error, and the value that atoi returns on error could also be returned on success. Not to mention that if an integer can't hold the result, the behavior is undefined. So really the only way to use atoi safely is to write or acquire a validation function for integers:
  1. #include <ctype.h>
  2. #include <limits.h>
  3.  
  4. int try_parse_int ( const char *s )
  5. {
  6. /* Base of the conversion */
  7. const unsigned base = 10;
  8.  
  9. /* Largest possible value without the least significant digit */
  10. const unsigned limit = UINT_MAX / base;
  11.  
  12. /* Least significant digit from the largest possible value */
  13. const unsigned top_digit = UINT_MAX % base;
  14.  
  15. unsigned overflow = 0; /* True if integer overflow occurs */
  16. unsigned sign = 0; /* Sign of the converted value */
  17.  
  18. unsigned temp = 0; /* The intermediate converted value */
  19. unsigned n = 0; /* Count of converted digits */
  20.  
  21. /* Save and skip over the sign if present */
  22. if ( *s == '-' || *s == '+' )
  23. sign = *s++ == '-';
  24.  
  25. /* Build the intermediate value */
  26. for ( ; isdigit ( *s ); s++, n++ ) {
  27. unsigned digit = *s - '0';
  28.  
  29. overflow = temp > limit
  30. || ( temp == limit && digit > top_digit );
  31.  
  32. if ( overflow )
  33. break;
  34.  
  35. /* Shift-add by the base */
  36. temp = temp * base + digit;
  37. }
  38.  
  39. if ( n > 0 ) {
  40. /* A conversion was made; check for overflow */
  41. if ( overflow
  42. || ( sign && temp > -INT_MIN )
  43. || ( !sign && temp > INT_MAX ) )
  44. {
  45. /*
  46.   The intermediate actually overflowed,
  47.   or converting it to int would overflow.
  48.   Either way it's an error to the caller
  49.   */
  50. return 0;
  51. }
  52. }
  53.  
  54. return n > 0 && *s == '\0';
  55. }
As you can see, there's a hell of a lot more to it than just making sure each character is a digit. You have to consider the sign and the range of the result before the string is guaranteed to be safe for atoi. Though of course, if you're going to all of this work to validate the string, you might as well convert it at the same time. strtol does that for you, which is why I keep saying that atoi is like gets in that it should be completely ignored.

>But that wasn't your question, so I'm leaving it that out in favor of the simple answer
It doesn't matter if it wasn't the question. We're here not only to answer questions, but to help people become better programmers. That means pointing out unrelated problems and correcting bad habits.
New members chased away this month: 3
Reply With Quote Quick reply to this message  
Join Date: Feb 2008
Posts: 1,669
Reputation: jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of 
Solved Threads: 123
jephthah's Avatar
jephthah jephthah is offline Offline
Posting Virtuoso

Re: Command Line Arguement, can't get it to read in an int

 
0
  #7
Apr 9th, 2008
i'm totally down with everything you're saying. and, technically speaking, you're absolutely right.

i also see value in aia's approach.

MY point was that

(1) you can't do this:
value=(int)argv[1];

(2) you must do this:
value = atoi(argv[1]);
(or similar, with strtol)

the poster obviously has a fundamental misunderstanding of how to get an int from command line argument.

now the place you're going with all your bulletproof errorchecking is just going to confuse the guy until he at least understands how to convert a char * to an int.

i dont think it's helpful to hand a beginner a fully fleshed out production-quality routine if they don't understand the basics.

i say let them send invalid args to the commandline and see what happens. otherwise they're just cutting and pasting your Beautiful Code without understanding what it really does.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,829
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 750
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Senior Bitch

Re: Command Line Arguement, can't get it to read in an int

 
0
  #8
Apr 9th, 2008
>i dont think it's helpful to hand a beginner a fully fleshed out production-quality routine
I agree. However, I also don't think it's helpful to dumb down your examples to the point of being blatantly wrong. My post was more for you than for him.

>i say let them send invalid args to the commandline and see what happens.
In which case it might work still "work", if the undefined behavior doesn't constitute a crash and they see atoi returning 0 as legitimate behavior. This is a case where testing with bad data isn't terribly instructive. Yet another reason not to use atoi.
New members chased away this month: 3
Reply With Quote Quick reply to this message  
Join Date: Feb 2008
Posts: 1,669
Reputation: jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of jephthah has much to be proud of 
Solved Threads: 123
jephthah's Avatar
jephthah jephthah is offline Offline
Posting Virtuoso

Re: Command Line Arguement, can't get it to read in an int

 
0
  #9
Apr 9th, 2008
hey i agree. i rarely use atoi, favoring strtol instead. and i always error check user inputs in my own code.

i am merely answering his simple question: "why doesnt X work?" with a simple answer: "because you can't use X like that... you must use Y instead."

now if you want to diverge into more advanced topics, and give him rope to hang himself... thats fine too. because if he tries to pass that code off in an assignment, and then gets called on to explain it -- and can't -- well, that's probably karma working like it should.

i mean, maybe he'll successfully study and understand what and why you're doing what you're doing, and learn some really valuable lessons. but, i think, just in my brief experience here with other similar posters, that is unlikely.

whatever. its all good. you're right, and you've already won. I'm scared of your chainsaw, okay? I'm just offering the answer at the same level of the question as it was posed. that's all.
Last edited by jephthah; Apr 9th, 2008 at 5:02 pm.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,829
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 750
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Senior Bitch

Re: Command Line Arguement, can't get it to read in an int

 
0
  #10
Apr 9th, 2008
>i rarely use atoi, favoring strtol instead. and i always
>error check user inputs in my own code.
I couldn't care less about your own code. You can use every bad habit in the book for your private programs, but the around here, we set a good example for programmers that usually don't know any better.

>why doesnt "x" work? with a simple answer: because
>you can't use "x" like that... you must use "y" instead.
In my experience, they're going to take your word as the word of God and use "y". If you're giving an example, make sure it's a good example, because it's a safe bet that someone will use it in a serious program.

Rather than give a specific solution (especially a bad one), explain why "x" doesn't work and the process that leads to "y". Then you can list standard functions that do "y". For example, "use atoi" is bad, but "you have to convert the string to an integer, and here are a few functions that do it for you...".

>you've already won.
I'm not here to win, but as long as you keep encouraging bad habits, I'll continue to feel like I've lost.
Last edited by Narue; Apr 9th, 2008 at 5:00 pm.
New members chased away this month: 3
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



Tag cloud for C
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC