Thread: problem with isdigit(), something causing segmentation fault

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    44

    Question problem with isdigit(), something causing segmentation fault

    I've came up with my own idea for a program, just to test mysel. Unfortunately I did not succeed.
    The idea is - accept input only if it is a number, return to scanf otherwise.
    Here is the code, it is giving me segmentation fault, and I have no idea what is wrong...
    Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <ctype.h>
    
    
    int main()
    {
                int i ,j;
                char d;
                char input[20];
                int transformed[20];
                            
                printf("Please enter a number\n");
                scanf("%s", input);
                for (i = 0; i < 20; i++) {
                transformed[i] = atoi(input[i]);
                }
                do {
                    for (j = 0; j <20; j++) {    
                        if (isdigit(transformed[j])) 
                        printf("Thanks for the number");
                        else {
                       printf("It is not a number. Please enter a number");
                            printf("Press r to repeat\n"); 
                        }
                    }                   
                scanf("%c", &d);
                } while (d != 'r');
                return 0;                        
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This is wrong:
    Code:
    transformed[i] = atoi(input[i]);
    atoi is intended to convert a null terminated string to an int. However, input[i] is neither an array of char that contains a null terminated string nor a pointer to the first character of a null terminated string; input[i] is a char.

    My suggestion is to write a function with this prototype:
    Code:
    int is_all_digits(const char *str);
    Implement this function to return 1 if all the characters in the string are digits, otherwise return 0. Use isdigit in a loop.

    This way, you can get rid of your transformed array. Rather, you just call is_all_digits(input) to determine if the input consists entirely of digits.
    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

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    44
    I appreciate Your help very much, however again it doesn't work properly. At least now, there's no segmentation fault

    isdigit seems to be not detecting numbers, and even though I clear the buffer, there is no possiblity to enter char d, to decide if we want to finish the loop.

    Code:

    Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <ctype.h>
    #include <string.h>
    
    int main()
    {
                int i, j, found, yes;
                char d;
                char input[20];
                
                do {
                        printf("Please enter a number\n");
                        scanf("%s", input);
                        j = 0;
                        for (i = 0; i < 20; i++) {
                            if (isdigit(input[i]) == 1) {
                                j++;
                            }
                        }    
                        if(j == strlen(input))    
                            yes = 1;
                        if (yes == 1)
                            found = 1;
                        else 
                            found = 0;
                        if (found == 1) 
                        printf("Thanks for the number");
                        else {
                       printf("It is not a number. Please enter a number");
                            printf("Press r to repeat\n"); 
                        }
                fflush(stdin);
                scanf("%c", &d);
                } while (d != 'r');
                return 0;                        
    }
    Thanks in advance!

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Hey there,

    I think that your biggest problem is that you are not initialising the variable "yes" to zero. (That's what I found when running your code)

    What I did to make your code work was to ditch the "yes" variable and let this line
    Code:
    if (j == strlen)
    change the variable "found" directly.

    From what I understand about fflush(stdin) is that it is for output buffers, not input buffers - See http://www.gidnetwork.com/b-57.html ("Things to avoid in C/C++ -- fflush(stdin) Part 2")

    I know that you are having trouble with input - use gets(input) instead of the scanf function and get rid of fflush(stdin) and use d=getchar();

    Another thing I realised was that even if the input was correct, you are checking for the input character 'r' -> That's fine, but you are not prompting the user what to do - For the user, the program would just seem to hang there.

    There are a few other things that you could do, but the code works without changing the other things, so I'll let you figure it out.
    Last edited by Click_here; 08-12-2012 at 06:48 PM. Reason: Fixing problem with link label

  5. #5
    Registered User
    Join Date
    Jul 2012
    Posts
    51
    Check line 17. More on isdigit() here.

    isdigit(2) = Returns a value different from zero (i.e., true).
    isdigit(a) = Returns zero (i.e., false).

    Double check what value is being returned by isdigit() with a printf statement.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by Click_here
    I know that you are having trouble with input - use gets(input) instead of the scanf function and get rid of fflush(stdin) and use d=getchar();
    Well don't use gets, either.

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Well don't use gets, either.
    Fair enough. I was just trying to help Pole get the code working - But to be complete, whiteflags is right.

    If you don't follow that link, it suggests to use fgets due to the risk of buffer overrun.

    If you are going to use fgets, look into ways of clearing/dealing with the input buffer on the event of too much input. This link gives you another explanation and how to use fgets and clearing the buffer on the event that your variable couldn't hold all the input IP Banned - GIDNetwork ("Things to avoid in C/C++ -- gets() Part 1")

  8. #8
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Click_here View Post
    If you are going to use fgets, look into ways of clearing/dealing with the input buffer on the event of too much input. This link gives you another explanation and how to use fgets and clearing the buffer on the event that your variable couldn't hold all the input IP Banned - GIDNetwork ("Things to avoid in C/C++ -- gets() Part 1")
    I wouldn't recommend that code. It's just as bad as gets(). They strcat() a dummy array of 50 chars to a buffer array of 5 chars --> BOOM
    But correctly implemented the idea wouldn't be bad.

    Kurt

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I wouldn't recommend that code. It's just as bad as gets(). They strcat() a dummy array of 50 chars to a buffer array of 5 chars --> BOOM
    But correctly implemented the idea wouldn't be bad.

    Kurt
    I didn't see that strcat in there -> A dummy variable should be a dummy variable! (unhappy face)

    Don't use that code.

    If your input is too large for your array, you need to read all the inputs into a dummy array -> From there I'd disregard all input, display an error message (i.e. "input too large - needs to be less than 'x') and prompt for input again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By raczzoli in forum C Programming
    Replies: 4
    Last Post: 07-18-2011, 06:49 PM
  2. strtok is causing segmentation fault
    By yougene in forum C Programming
    Replies: 11
    Last Post: 03-08-2008, 10:32 AM
  3. A libdc1394 library function is causing a segmentation fault
    By Phanixis in forum Linux Programming
    Replies: 7
    Last Post: 10-16-2007, 12:44 PM
  4. problem with segmentation fault
    By cBegginer in forum C Programming
    Replies: 13
    Last Post: 05-15-2005, 11:51 AM
  5. strcat causing segmentation fault?
    By jbsloan in forum C Programming
    Replies: 2
    Last Post: 04-02-2005, 10:42 AM

Tags for this Thread