C: strtok 传递分段错误 [英] C: strtok delivers segmentation fault

查看:28
本文介绍了C: strtok 传递分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试逐行读取文件,并对每一行进行标记,其中的字符串由空格和制表符分隔.但是,当我运行我的程序时,当我尝试打印令牌时出现 Segmentation Fault 错误.我不明白为什么会发生这种情况,因为我使用缓冲区作为字符串来标记并检查标记是否为空.下面是我的代码:

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 Fault error when I try to print the token. I don't understand why this is happening, as I am using a buffer as the string to tokenize and checking if the token is null. Below is my code:

#include <stdio.h>
#include <stdlib.h>

#define MAX_LINE_LENGTH 70

int main(void)
{
    FILE * testFile;
    char buf[MAX_LINE_LENGTH];
    testFile = fopen("test_file.txt", "r");

    if (testFile == NULL)
    {
        printf("Cannot open test_file.txt.\n");
        exit(0);
    }

     while (fgets(buf, sizeof(buf), testFile) != NULL) {
        char *token = strtok(buf," \t"); 


        while (token != NULL) 
        {
            token = strtok(NULL, " \t"); 

            if (token != NULL) {
             printf("%s\n", token);
            }
        }
    }

    exit(1);
}

以下是test_file.txt的内容:

String1 String2 String3
String4 String5 String6
String7 String8 String9

推荐答案

两个有用的提示 -- (1) 启用编译器警告,例如最小 -Wall -Wextra -pedantic 用于 gcc/clang 或 /W3 用于 VS(任何其他编译器都有类似的选项),并且在没有警告的情况下编译之前不接受代码;(2) #include 其中定义了strtok.

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.

除了@dreamer 指出的缺乏验证之外,您必须对 strtok 使用隐式定义.您应该会收到这些方面的编译器警告.不要忽略任何警告,而是去修复它,它通常会告诉您问题代码所在的确切行.

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.

接下来,不要硬编码文件名.将文件名作为第一个参数传递给程序(或默认从 stdin 读取)同样简单.您的第二个选择是将文件名作为程序的输入.

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;
}

(注意:您需要包含 '\n' 作为分隔符,以防止额外的 '\n' 成为一部分每行的最后一个标记)

(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)

示例使用/输出

$ ./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.

这篇关于C: strtok 传递分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆