Thread: segmentation fault with strtod

  1. #1
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252

    segmentation fault with strtod

    Hey guys im making a clock program which the user enters the time. However if the user types say 3 45 why am i getting a segmentation fault. Im using strstod it gets the start of the input 3 for the hour. But for m it will store say 40 instead of 45 so its not converting properly. Not sure why ? Could this be the cause of the seg fault?

    Code:
    int getClockInput(int optionStats[NUM_OPTION_STATS])
    {
        int h, m;
        int display_error, end_of_input;
        char *start;
        char *end;
    
        printf("\nEnter <hours> <minutes>: ");
    
        fgets(start, MAX_CHAR, stdin);
        h = (int) strtod(start, &end);
        m = (int) strtod(end, &end);
    
        if(start[strlen(start)-1] !='\n')
        {
              readRestOfLine();
    
        }
        else
        {
          start[strlen(start)-1] = '\0';
        }
        /*scanf("%d%d", &h, &m);*/
        display_error = displayClock(optionStats,h, m);
        
        if (display_error)
        {
          printf("Incorrect data received for hours and minutes\n");
          return 0;
        }
    
        return 0;
    
    }

  2. #2
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    You didn't point start to an array or malloc'd memory, it's uninitialized.

  3. #3
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    would i do something like this char *start[SIZE]

  4. #4
    Registered User Noir's Avatar
    Join Date
    Mar 2007
    Posts
    218
    That'd give you an array of pointers, so you'd probably rather have this:
    Code:
    char start[MAX_CHAR];

  5. #5
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    Yep thats right. Is there anything else i need to change i still get a seg fault?

  6. #6
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    This is the other portion of the code in another file gdb shows a seg fault when it updates the clock with hr and hs symbolds with the outter and inner for loop. Not sure why?

    Code:
    int displayClock(int * optionStats, int h, int m)
    {
        char clock[9][20] = { /* The array to hold the hard-coded clock */
            "        12         ",
            "   11        01    ",
            " 10            02  ",
            "                   ",
            "09      .       03 ",
            "                   ",
            " 08            04  ",
            "   07        05    ",
            "        06         "
          };
    
    	/* Row and column numbers in clock array for hour positions. For
    	 * example, the "06" in the clock display is stored at position
    	 * [8, 8] in the clock matrix (see above) */
        const int hr[13] = {0, 1, 2, 4, 6, 7, 8, 7, 6, 4, 2, 1, 0};
        const int hc[13] = {0, 13, 15, 16, 15, 13, 8, 3, 1, 0, 1, 3, 8};
    
    	/* Hour and minute codes */
        const char hs = 'H', ms = 'm';
    
        int i, j; /* Declare other variables as needed */
        int a, b;
    	/* The next 5 comments require code to be developed by you! */
    
    	/* Ensure that h and m are in range and, if not, return
    	 * appropriate error value. Otherwise adjust h if it is 0 or it
    	 * exceeds 12
    	 */
         if(h>12 || h<1)
         {
                printf("Hours is invalid 1 - 12\n");
                return FALSE;
         }
             
    
         if(m<0 || m>=60)
         {
                printf("Minutes is invalid 0 - 60\n");
                return FALSE;
         }
             
        /* Now update the clock array accordingly, with the hour symbol */
    
    	/* Round m to the nearest hour position */
    
    	/* Update clock with minute symbol, taking into account a "clash"
    	 * with the hour symbol 
    	 */
              for(a=0; a<9; a++)
            {
            
              for(b=0; b<19; b++)
              {
                     clock[hr[h]][hc[h]] = hs;
                     clock[hr[h]][hc[h]+ 1] = hs;
                   
                  
                      
                    
                   
               }
                     
                     clock[hr[m]][hc[m]] = ms;
                     clock[hr[m]][hc[m]+ 1] = ms;
             }     
    
        
    	/* Display the clock */
        for (i = 0; i < 9; i++)
        {
            for (j = 0; j < 19; j++)
        	    printf("%c", clock[i][j]);
            printf("\n");
        }
        printf("\n");
    
        return 0;
    }

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    well you need to tokenize the string first to get the hours and min seperate. And then you need to convert them into double using strtod.

    use sscanf to tokenize the sting and you can convert then into float as well.

    Code:
    #include<stdio.h>
    
    int main()
    {
        char str[]="3 45";
        float h, m;
        
        sscanf(str,"%f %f",&h,&m);
        
        printf("%f %f",h,m);
        
        getchar();
        return 0;
    }
    ssharish2005

  8. #8
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    i cant use anything else but fgets by the way

  9. #9
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    well, it was just an exmple to show you how to use sscanf. If u are restricted to fgets then get the input through fgets and then tokenize the string through sscnaf, rather than strtod.

    Or if you still need to use strtod, allocate memory for both start and end char pointer. And the send then as a parmater to the strtod function.

    It was giving sef fault becuase u allocated memory for start but not for end

    Code:
    start = malloc (20);
    end  = malloc (10);
    ssharish2005

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    char buff[BUFSIZ];
    fgets( buff, sizeof buff, stdin );
    That's how you read a line.

    To read two ints from that line, without using sscanf,
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main( void ) {
        char buff[] = "12 45";
        char *endp;
        int  hr,mn;
        hr = (int)strtol(buff,&endp,10);
        mn = (int)strtol(endp,NULL,10);
        printf("%d %d\n", hr, mn );
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    Ok just another question how come your using strtol instead of strtod?

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well strtol() and strtoul() are for integer values, whereas strtod() is for doubles.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Musicman - Canora
    Join Date
    Aug 2005
    Location
    Melbourne
    Posts
    252
    Hey guys i have changed it to what Salem said to do and i still get a seg fault and when i run the debugger it always seems to point to the code below

    clock[hr[m]][hc[m]] = ms;
    clock[hr[m]][hc[m]+ 1] = ms;

    maybe im accessing part of the array which isnt there in the for loop im not sure?

    But i checked the values of m and h and they are being correctly seperated for hours and minutes now with strol working with it. But still getting seg fault not?


    Code:
      for(a=0; a<9; a++)
            {
            
              for(b=0; b<19; b++)
              {
                     clock[hr[h]][hc[h]] = hs;
                     clock[hr[h]][hc[h]+ 1] = hs;
                   
                  
                      
                    
                   
               }
                     
                     clock[hr[m]][hc[m]] = ms;
                     clock[hr[m]][hc[m]+ 1] = ms;
             }

  14. #14
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    and what is changing in the loop?
    where are the var declarations?
    and initializations?

    your code shows nothing usefull
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  15. #15
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    Within your loop, m (which stands for minutes) goes from 0 to 59, yet your array hc is of size 13. The access hc[m] accesses illegal memory. The same goes for hr[m].

    And why is your loop body completely independent of a and b ?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why am I getting segmentation fault on this?
    By arya6000 in forum C++ Programming
    Replies: 6
    Last Post: 10-12-2008, 06:32 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM