Thread: I'm getting a segmentation fault when I try to strstr.

  1. #1
    Registered User
    Join Date
    Jul 2021
    Posts
    1

    I'm getting a segmentation fault when I try to strstr.

    Am I being dumb and missing a blatant code error?
    I'm pretty new to the C language so keep that in mind if you see the mistake.

    I'll include everything I think you'll need in here.

    where the student structure is defined

    Code:
    typedef struct {
    
    
      char Nome[64];
      char Cognome[64];
      char Matricola[64];
    
    
    } student;

    Where the values get inserted:

    Code:
    int w_input_handler (void) {
    
    
        int records = 0;
        int index   = 0;
    
    
        printf("\nHow many students would you like to add?\n");
        scanf("%d", &records);
    
    
        file_array = (student *)  malloc(records * sizeof(student));
        if (file_array == NULL) {
                printf("\nMemory allocation error\n");
                return -1;
        }
    
    
        for (index = 0; index < records; index++) {
    
    
    
    
                printf("\nEnter name of person %d: ", (index+1));
                scanf("%s", (*(file_array + index)).Nome);
    
    
                printf("\nEnter surname of person %d: ", (index+1));
                scanf("%s", (*(file_array + index)).Cognome);
    
    
                printf("\nEnter student id of person %d: ", (index+1));
                scanf("%s", (*(file_array + index)).Matricola);
    
    
        }
    
         new_text_file = fopen(o_option_argument, "ab");
    
        if (new_text_file) {
                for(index = 0; index < records; index++) {
                    return_value = fwrite((file_array + index), sizeof(student), 1, new_text_file);
                }
        }
    
    
    }

    Here's where I'm getting the segmentation fault on the strstr function:

    the *input that gets passed as the value here is just a basic (find_name was declared as a pointer, of course)

    Code:
    scanf("%s", find_name);
    Code:
    int find_name_function(char *input) {
    
    
        int records           = 30;
        int index             =  0;
        int number_of_matches =  0;
        int return_value;
        char *ret             = NULL;
    
    
        student *read_file_array  = (student *) malloc(records * sizeof(student));
    
    
        new_text_file = fopen(o_option_argument, "rb");
      
        if (new_text_file) {
    
    
            while (1) {
    
    
                return_value = fread((read_file_array + index), sizeof(student), 1, new_text_file);
                if (return_value != 1) {
                    break;
                }
    
    
                ret = strstr(((*(read_file_array + (index))).Nome), input);
                if (ret) {
    
    
                    printf("\nFound student:\n");
                    printf("\nName >%s<\n", (*(read_file_array + (index))).Nome);
                    printf("\nSurname >%s<\n", (*(read_file_array + (index))).Cognome);
                    printf("\nMatricola >%s<\n", (*(read_file_array + (index))).Matricola);
                    number_of_matches++;
                }
    
    
                index++;
            }
        }
    I'm sorry if it seems a bit confusing or anything like that, I'd gladly give anything else you might want

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I would suggest doing a bit more error checking, and making sure that you free what you malloc and fclose what you fopen. For example, you might have something along the lines of:
    Code:
    int w_input_handler(void) {
        int records = 0;
        int index   = 0;
        int records_written = 0;
    
        printf("\nHow many students would you like to add?\n");
        if (scanf("%d", &records) != 1 || records < 1) {
            fprintf(stderr, "\nInvalid number of students\n");
            return -1;
        }
    
        file_array = (student *) malloc(records * sizeof(student));
        if (file_array == NULL) {
            fprintf(stderr, "\nMemory allocation error\n");
            return -1;
        }
    
        for (index = 0; index < records; index++) {
                printf("\nEnter name of person %d: ", (index + 1));
                scanf("%63s", file_array[index].Nome);
    
                printf("\nEnter surname of person %d: ", (index + 1));
                scanf("%63s", file_array[index].Cognome);
    
                printf("\nEnter student id of person %d: ", (index + 1));
                scanf("%63s", file_array[index].Matricola);
        }
    
        new_text_file = fopen(o_option_argument, "ab");
        if (!new_text_file) {
            fprintf(stderr, "\nCould not open file to append\n");
            free(file_array);
            return -1;
        }
        records_written = fwrite(file_array, sizeof(student), records, new_text_file);
        fclose(new_text_file);
    
        free(file_array);
    
        return records_written;
    }
    Notice that I have used "%63s" to avoid buffer overflow in the use of scanf to read strings, and then I did the fwrite in a single call since you already have an array at hand. I have also used file_array[index].Nome instead of (*(file_array + index)).Nome because the former tends to be easier to read and hence less likely to have a typo.

    The thing is that w_input_handler returns the number of records written. So the caller could save this somewhere, and then you can have something like:
    Code:
    int find_name_function(int records, const char *input) {
        int records_read;
        int index             =  0;
        int number_of_matches =  0;
        int return_value;
    
        student *read_file_array = malloc(records * sizeof(student));
        if (!read_file_array) {
            fprintf(stderr, "\nMemory allocation error\n");
            return -1;
        }
    
        new_text_file = fopen(o_option_argument, "rb");
        if (!new_text_file) {
            fprintf(stderr, "\nCould not open file for reading\n");
            free(read_file_array);
            return -1;
        }
    
        records_read = fread(read_file_array, sizeof(student), records, new_text_file);
        fclose(new_text_file);
    
        // ... check records_read?
    
        for (index = 0; index < records_read; ++index) {
            if (strstr(read_file_array[index].Nome, input)) {
                printf("\nFound student:\n");
                printf("\nName >%s<\n", read_file_array[index].Nome);
                printf("\nSurname >%s<\n", read_file_array[index].Cognome);
                printf("\nMatricola >%s<\n", read_file_array[index].Matricola);
                number_of_matches++;
            }
        }
    
        // ...
    Alternatively, you could write the number of records at the start of the file, but then you would want to flag an error if the number of records written does not match the number of records you expect to write... but perhaps it is a good idea to flag that anyway.
    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
    Oct 2019
    Posts
    82
    Code:
    ret = strstr(((*(read_file_array + (index))).Nome), input);
    Should not the above follow the same syntax as the below?

    Code:
    scanf("%s", (*(file_array + index)).Matricola);
    Just wondering

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Also, the array access in code like this:

    Code:
    (*(file_array + index)).Matricola
    is more usually written like this:

    Code:
    file_array[index].Matricola

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In GDB no segmentation fault but while running segmentation fault
    By Tamim Ad Dari in forum C++ Programming
    Replies: 2
    Last Post: 12-10-2013, 11:16 AM
  2. using strstr (Segmentation fault)
    By Isaacx in forum C Programming
    Replies: 3
    Last Post: 02-16-2010, 08:59 PM
  3. What can cause a Segmentation fault?
    By Mikecore in forum C Programming
    Replies: 3
    Last Post: 01-04-2006, 12:42 AM
  4. strstr() segmentation fault help
    By Rpog in forum C Programming
    Replies: 7
    Last Post: 04-14-2004, 09:40 AM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM

Tags for this Thread