C: strtok delivers segmentation fault

前端 未结 2 1800
挽巷
挽巷 2021-01-28 05:52

I am trying to read a file line by line, and tokenize each line, which have strings separated by spaces and tabs. However, when I run my program, I get the a Segmentation

相关标签:
2条回答
  • 2021-01-28 06:41

    Looks like you are printing without checking for NULL for token pointer.

    If you need to print all tokens you also need to print inside while loop after strtok system call with addition to non-NULL check for token.

    0 讨论(0)
  • 2021-01-28 06:58

    Two helpful tips -- (1) enable compiler warnings, e.g. minimum -Wall -Wextra -pedantic for gcc/clang or /W3 for VS (any other compiler will have similar options), and do not accept code until it compiles without warning; (2) #include <string.h> where strtok is defined.

    In addition to the lack of validation pointed out by @dreamer, you must be using an implicit definition for strtok. You should receive a compiler warning along those lines. Don't ignore any warning, instead go fix it, it will generally tell you the exact line the problem code is on.

    Next, don't hardcode filenames. It is just as simple to pass the filename as the first argument to your program (or read from stdin by default). Your second option is to take the filename as input to your program.

    Putting those together, you could do something simple like:

    #include <stdio.h>
    #include <string.h>
    
    #define MAX_LINE_LENGTH 70
    #define DELIM " \t\n"
    
    int main (int argc, char **argv) {
    
        char buf[MAX_LINE_LENGTH];
        /* use filename provided as 1st argument (stdin by default) */
        FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    
        while (fgets (buf, sizeof buf, fp))
            for (char *p = strtok(buf, DELIM); p; p = strtok(NULL, DELIM))
                puts (p);
    
        if (fp != stdin)   /* close file if not stdin */
            fclose (fp);
    
        return 0;
    }
    

    (note: you need to include '\n' as a delimiter character to prevent the additional '\n' from being part of the last token in each line)

    Example Use/Output

    $ ./bin/strtokfile test_file.txt
    String1
    String2
    String3
    String4
    String5
    String6
    String7
    String8
    String9
    

    Look things over and let me know if you have questions.

    0 讨论(0)
提交回复
热议问题