Thread: Segmentation Fault?

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    119

    Segmentation Fault?

    I can do the problem in java, but I was wondering if I could write the code this way in C. Can I store a series of pointers to strings in an array? So that array[0] could contain a pointer to an string in memory? I get a segmentation fault when i run my code, and a bunch of formatting errors. The point is to create a simple mail merge type program, where each line of the file being read looks like |string|string|string| etc.. up to 9 fields.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAXSIZE 25
    
    int main( int argc, char *argv[] )
    {
        char line[ MAXSIZE ]; //hold lines of file
        char fields[ MAXSIZE ]; //hold tokenized strings (need to be a pointer?)
        char *token = NULL;
        FILE *read = NULL; //file to be read
        int i;
    
        read = fopen( "data.txt", "r" );
    
        while( !feof( read ) )//read each record
        {
            fgets( line, MAXSIZE, read );
            token = strtok( line, "|" ); //tokenize the line
            
            i = 0;
            while( token )
            {
                fields[ i ] = token; //store pointers in array (if possible?)
                token = strtok( NULL, "|" );
                i++;
            }
    
            //formatting...
            printf( "Welcome back, %s %c\n", fields[ 1 ], '!' ); 
            printf( "We hope that you and all the members\n"); 
            printf( "of the %s %s", fields[ 0 ], " family are constantly\n" ); 
            printf( "reminding your neighbors there\n"); 
            printf( "on %s %s", fields[ 5 ], " to shop with us\n" ); 
            printf( "As usual, we will ship your order to\n"); 
            printf( "%4s %2s %2s %2s\n", fields[ 3 ], fields[ 1 ], fields[ 2 ], fields[ 0 ] ); 
            printf( "%4s %2s\n", fields[ 4 ], fields[ 5 ] );
            printf( "%4s %s %s %s\n", fields[ 6 ], ", ", fields[ 7 ], fields[ 8 ] );    
        }
    
        return EXIT_SUCCESS;
    }
    Code:
    Errors:
    
    merge.c: In function âmainâ:
    merge.c:25: warning: assignment makes integer from pointer without a cast
    merge.c:30: warning: format â%sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:32: warning: format â%sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:34: warning: format â%sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:36: warning: format â%4sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:36: warning: format â%2sâ expects type âchar *â, but argument 3 has type âintâ
    merge.c:36: warning: format â%2sâ expects type âchar *â, but argument 4 has type âintâ
    merge.c:36: warning: format â%2sâ expects type âchar *â, but argument 5 has type âintâ
    merge.c:37: warning: format â%4sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:37: warning: format â%2sâ expects type âchar *â, but argument 3 has type âintâ
    merge.c:38: warning: format â%4sâ expects type âchar *â, but argument 2 has type âintâ
    merge.c:38: warning: format â%sâ expects type âchar *â, but argument 4 has type âintâ
    merge.c:38: warning: format â%sâ expects type âchar *â, but argument 5 has type âintâ

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    fields should be char *, not char.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > char fields[ MAXSIZE ];
    char *fields[ MAXSIZE ];
    would be more consistent with all the usage of the array you have.

    > while( !feof( read ) )
    Read the FAQ as to why feof() to control a loop is bad.

    Do this instead
    Code:
        while( fgets( line, MAXSIZE, read ) != NULL )//read each record
        {
            fgets( line, MAXSIZE, read );
            token = strtok( line, "|" ); //tokenize the line
            // etc
        }
    > while( token )
    while( token && i < MAXSIZE )
    would be much safer.

    A final
    fclose(read);
    would be good as well.
    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.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    > char fields[ MAXSIZE ];
    while( token && i < MAXSIZE )
    would be much safer.
    Yes, but assuming that the string has LESS tokens than it's own length should be safe, so I don't think that is likely to happen (actually, I fail to see how strtok could give you a number of tokens less than HALF of the size of the original string, because the token will consist of one non-separator character and one separator character, so two characters are needed to make a single token). However, if the size of the fields array is different from (smaller than half + 1 of) MAXSIZE, then this is definitely necessary to prevent overflow of the token pointers.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    True, but I like to put the array subscript into the conditional as a matter of habit, even when there seems little chance of it being critical to the code.
    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.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    True, but I like to put the array subscript into the conditional as a matter of habit, even when there seems little chance of it being critical to the code.
    Yes, I agree, better safe than sorry.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    119
    Thanks guys, i made the necessary changes and it's almost working. I get a segmentation fault again, but it's after a couple of the fields get printed. So at least I know its partially working. It seems that everything is working, I am storing the tokens inside the array and able to print the proper fields. But I don't get past the first record, in fact, I don't even finish the first record. I get no errors upon compiling, but this is what my program produces.

    Code:
    Welcome back, "Peter" ! <-----Tokenizing works, this was the second entry stored
    We hope that you and all the members
    of the "Johnson"  family are constantly <-----Storage of tokens in array seems to work
    reminding your neighbors there
    Segmentation fault <-------Is this a memory issue?  Can someone clarify...

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Are you sure you get the right number of tokens back. You are explicitly accessing fields[n] up to 8, which means that i should be 9 to allow for that - or you need to check the field to see it it's been filled in [best done by assiging
    Code:
    char *fields[MAXSIZE] = { 0 };
    so that you have a zero field if it's not been assigned by the code].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Post your latest version of this program with all the changes you've made.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    119
    when i was sitting down for breakfast, i thought the buffer size might have been too small because I forgot to change the constant. After pushing it to 100, instead of 25 the output is properly generated, and no segmentation fault occurs. However, formatting in C is beginning to annoy me. The first block of output is properly formatted, but later blocks deviate by a space or two although I am using &#37;4s for each. Any formatting tips?

    p.s. Just so i'm clear as to whats going on in my program, I was storing a pointer to each string(token) inside the array. So when field[0] was called, inside was a pointer, which pointed to a string, and that's why I could store a string inside each index of the array?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, fields will hold a pointer to the somewhere in "line". But my point was more that if you don't set the fields[x] to a valid string, then you can NOT print that.

    Not sure what you mean by formatting not working. If you give a width for a string field, however, it will still print WIDER than that if I remember correctly.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 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