简体   繁体   中英

Getting a seg fault when tokenizing string in c

I just started programming in C a few days ago. My program opens a file, reads it line by line then removes stuff I don't need (brackets, newline,etc..), then once I just have the data in a comma separated format I want to add it to an array(then add that array to a array of arrays). I'm at the point where I am tokenize the comma separated string but I keep getting EXC_BAD_ACCESS, Could not access memory. when I run it in debugger.

What am I doing wrong? Here's the section of my code that is giving me the problem:

//now data(variable: line) looks like this:  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
char *str_ptr;
str_ptr = strtok(line, ",");
  for(; str_ptr != NULL ;){
    fprintf(stdout, "%s\n", str_ptr);
    str_ptr = strtok(NULL, ",");
  }

Here's my entire code:

#include <stdio.h>

int main() {

    char line[1024];
    FILE *fp = fopen("/Users/me/Desktop/output.txt","r");

    printf("Starting.. \n");
    if( fp == NULL ) {
        return 1;
    }
    int count = 0;
    int list[30]; //items will be stored here

    while(fgets(line, 1024, fp) != EOF) {
        count++;
        //parse the text in the line Remove the open bracket, then remove the last newline,comma and close bracket
        // data looks like this: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],
        size_t len = strlen(line);
        memmove(line, line+1, len-4);
        line[len-4] = 0;
        printf("%s \n",line);

        //parse the numbers in the char
        //now data looks like this:  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
        char *str_ptr;
        str_ptr = strtok(line, ",");
          for(; str_ptr != NULL ;){
            fprintf(stdout, "%s\n", str_ptr);
            str_ptr = strtok(NULL, ",");
          }


        //for testing just stop the file after two lines
        if (count == 2) {
            break;
        }

        
        if ( count > 1000000) {
            printf("count is higher than 1,000,000 \n");
            count = 0;
        }
    }
    printf(" num of lines is %i \n", count);

    return 0;
}

Other than the debugger I'm not sure how to get meaningful information in this case.

Update

Sorry, didn't know how to do this. Here is a copy of the stack in the debugger (other than main, if I click on them they all say "No source available for .." then the items in the list:

Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)    
    strlen() at 0x7fff875ef4f0  
    __vfprintf() at 0x7fff875908c3  
    vfprintf_l() at 0x7fff8758f18e  
    fprintf() at 0x7fff87598d9a 
    main() at learningC.c:77 0x100000d5a    

fgets returns a NULL on error or EOF. Check for that not for EOF .

while(fgets(line, 1024, fp) != NULL){

I don't see anything wrong if the input file is always valid. I tried to compile and run it on my Mac and it's working really fine. Maybe you can upload sample file somewhere so we can see what's going on exactly, because the code in memmove part is too vulnerable for the invalid input (blank line or short line for example). I would suggest to change it to

char* data = line;
size_t len = strlen(line);
if (len > 3) {
    line[len - 3] = '\0';
    data++;
}

char *str_ptr;
str_ptr = strtok(data, ",");
for(; str_ptr != NULL ;){
    fprintf(stdout, "%s\n", str_ptr);
    str_ptr = strtok(NULL, ",");
}

My code is still far from perfect data validation, but at least it won't throw seg fault on blank line.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM