Thread: Some help for a Noobie!

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    8

    Some help for a Noobie!

    Another Noobie,

    Hi everyone. Im Barry, i just started using C over the last 4 months as part of my college course. I have a basic understanding of the language.

    I have problems with some of the error trapping in my programming assignment and i was hoping you might be able to point me in the right direction.

    Firstly:
    Code:
    void menu1(void)
    {
    void FileName (void) ;
    int iChoice;
    puts("\t\t\t\tMENU\n");
    puts("\t\t\t1.\tEnter File Name");
    puts("\t\t\t2.\tExit");
    printf("Enter your choice: ");
    scanf_s("%d", &iChoice);
    
    switch (iChoice)
    {
    case 1:
    	FileName();
    case 2:
    	exit(0);
    default:
    	puts("Please select either 1 or 2");
    	menu1();
    } /*end switch*/
    
    } /*end menu1*/
    I have the program compiling fine and looping when any number other than 1 or 2 are entered but when i enter a character it goes into an infinite loop.

    This is probably pretty simple to fix but like i said im a noobie. Id appreciate any help you can give me!!

    Thanks
    Barry

  2. #2
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    It has to do with the switch statement jumping to a case based on an integer value, not a character value. You're assigning iChoice a character value (character object != integral object, an unsigned char is however). You might want to check the value of iChoice before continuing to the switch case.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by barryr View Post
    Code:
    scanf_s("%d", &iChoice);
    I'm not familiar with scanf_s, but scanf does this when you use %d and enter a character. A possible solution might be to use getchar() and delete 48, to get the numerical value from the ascii code. When doing this you can also reject anything not in the range of 0-9.

    ASCII:
    Code:
    48  0,    49  1,    50  2,    51  3,    52  4,    53  5,    54  6,    55  7,  56  8,    57  9

  4. #4
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    scanf_s is the "secure" version if you're using VS. Same goes for fopen, fwrite, etc. It is functionally the same as its "nonsecure" counter part.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Ok but does it share the infinite loop "feature" of it's scanf cousin?

  6. #6
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    It should (not that it's a good thing), like I said they are functionally the same, the secure versions usually checked for buffer overflows, null pointers, etc.

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    8
    Quote Originally Posted by Subsonics View Post
    I'm not familiar with scanf_s, but scanf does this when you use %d and enter a character. A possible solution might be to use getchar() and delete 48, to get the numerical value from the ascii code. When doing this you can also reject anything not in the range of 0-9.

    ASCII:
    Code:
    48  0,    49  1,    50  2,    51  3,    52  4,    53  5,    54  6,    55  7,  56  8,    57  9
    When you say getchar() and delete 48 what do you mean exactly? I understand getchar but how do i delete 48?

    Sorry for being clueless

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by barryr View Post
    When you say getchar() and delete 48 what do you mean exactly? I understand getchar but how do i delete 48?

    Sorry for being clueless
    If you use getchar, and enter 0 on stdin, that will correspond to ascii value 48. So, before you can use what getchar got for you as a number, subtract 48 as an offset.

    The list I supplied is from ascii man page and shows the ascii codes for 0-9. So you could do something like this.

    Code:
    c = getchar();
    c -= 48;
    
    // Then you can use c as a number here.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You should not rely on its ascii representation nor use it anywhere in the program because it is difficult to understand what it means.
    You can use is_digit to check if it is indeed a number. Then you can subtract by '0' to get the "real" number in integer format.
    Example:
    c = getchar();
    c -= '0';
    Do NOT subtract by 48. It's known as a magic number. A number thrown in somewhere which you might not have any idea of what it means. Therefore, subtract by '0'. That will give it a more meaningful description.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Elysia View Post
    You should not rely on its ascii representation nor use it anywhere in the program because it is difficult to understand what it means.
    You can use is_digit to check if it is indeed a number. Then you can subtract by '0' to get the "real" number in integer format.
    Example:
    c = getchar();
    c -= '0';
    Do NOT subtract by 48. It's known as a magic number. A number thrown in somewhere which you might not have any idea of what it means. Therefore, subtract by '0'. That will give it a more meaningful description.
    Agreed, that is a good advice. Or use a #define, it was just a quick example, it also does not check for values above 9 or below 0.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, it does not. That might be the job of is_digit to make sure it really is a digit before subtracting.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485

    Smile

    Quote Originally Posted by Elysia View Post
    Yes, it does not. That might be the job of is_digit to make sure it really is a digit before subtracting.
    But both getchar() and isdigit() would fail if the input was more than one byte.

    But for this example it really isn't necessary to do any conversion at all and just use chars. The scanf could stay as well if it must, if only iChoice and %d is changed to char.

    Code:
    char iChoice;
    scanf("%c", &iChoice);
    
    switch(iChoice)
    { 
                    case '1':
                    {
                            puts("input was a one");
                            break;
                    }
                    case '2':
                    {
                            puts("input was a two");
                            break;
                    }
                    default:
                    {
                            puts("make a valid choice");
                    }
    }

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Also involves a lot more code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Yep, solving the problem by avoiding it. :-D

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There are more elegant solutions...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. putting text onto the next line...lol...noobie questions
    By JOlszewski in forum C Programming
    Replies: 2
    Last Post: 01-24-2006, 04:02 PM
  2. A fourth noobie question - namespace std?
    By Noobie in forum C++ Programming
    Replies: 24
    Last Post: 08-12-2005, 02:10 PM
  3. Resource ICONs
    By gbaker in forum Windows Programming
    Replies: 4
    Last Post: 12-15-2003, 07:18 AM
  4. C++ program jumps for noobie
    By bandito9111 in forum C++ Programming
    Replies: 3
    Last Post: 03-01-2003, 01:48 AM
  5. A fifth noobie question-enum color?
    By Noobie in forum C++ Programming
    Replies: 19
    Last Post: 01-21-2003, 09:30 AM