【问题标题】:C strtok and strcpyC strtok 和 strcpy
【发布时间】:2013-04-23 21:20:06
【问题描述】:

我有一个文本文件,类似于以下内容:

Name1: ID1
Name2: ID2
Name3: ID3

我正在尝试解析它以获取

Name1
Name2
Name3

存储在变量中。

我写了以下函数:

/*
 *  filename    Name of file to read
 *  result      The result will be stored here
 */

void readlist(char* filename, char* result) {
    FILE *fp;
    char buffer[2048];
    memset((void *)result, '\0', BUFFER_SIZE);

    fp = fopen(filename, "r");

    while (fgets(buffer, sizeof(buffer), fp)) {
        char *token = NULL;
        token = strtok( buffer, ":" );
        strcat(result, token);
    }

    fclose(fp);
}

但是当我调用它时:

char result[2048];
readlist("test.txt", result);
printf("%s", result);

我得到一个空输出。看来 strtok() 搞乱了数据,但我可能错了。

我在这里做错了什么?

提前谢谢你!

【问题讨论】:

    标签: c parsing strtok strcpy


    【解决方案1】:

    确保将 result 初始化为空字符串。要么

    char result[2048] = "";
    

    在调用者中,或

    result[0] = '\0';
    

    在 readlist() 的顶部。

    【讨论】:

    • 谢谢,但这无济于事。如果我将 while 循环更改为 strcat(result, buffer);它可以很好地返回整个文件的内容。
    【解决方案2】:

    在调用readlist 之前或之后,您从未初始化结果。

    只需在调用readlist之前添加:strcpy(result, "");

    【讨论】:

    • 感谢回复,但这不是问题(我试过了)。
    • 我想知道您的问题是否在于您正在读取带有 RETURNS 和 LINEFEEDS 的文件,而 RETURNS 会弄乱您的输出并使其看起来好像没有任何匹配。我建议您将输出重定向到一个文件(例如./program > save.output)并在编辑器中检查输出。
    【解决方案3】:
    char result[2048];
    

    初始化此语句,否则结果将包含垃圾值作为其auto 变量。

    所以在你的main函数中调用readlist()之前使用char result[2048] = "";

    【讨论】:

    • @max 您是否检查过文件是否正确并且您可以读取该文件?
    【解决方案4】:

    我运行了你的代码(或者至少,我从你的代码的 sn-ps 创建了一个程序),它对我来说很好:

    #include <stdio.h>
    #include <string.h>
    
    void readlist(char* filename, char* result);
    
    int main(void) {
    char result[2048];
    readlist("test.txt", result);
    printf("%s", result);
    }
    
    void readlist(char* filename, char* result) {
        FILE *fp;
        char buffer[2048];
    
        fp = fopen(filename, "r");
    
        while (fgets(buffer, sizeof(buffer), fp)) {
            char *token = NULL;
            token = strtok( buffer, ":" );
            strcat(result, token);
        }
    
    
        fclose(fp);
    }
    

    当我在你的输入文件上运行它时,我得到了输出

    Name1Name2Name3
    

    完全符合预期。

    这是在 Mac OS 上使用 gcc 编译器版本 4.2.1 。它表明您的代码并没有您想象的那么远(编译器在开始之前是否将字符串初始化为 0 显然取决于实现)。不过为了安全起见,您需要确保您的初始结果全为零。你可以这样做

    char result[2048] = {'\0'};
    

    这将保证所有元素都初始化为零。另一种方法是使用

    static char result[2048];
    

    由于声明static 的任何变量都将被初始化为零。

    最后,像

    result[0] = '\0';
    

    将以零长度开始字符串 - 后面的任何内容都无关紧要。这可能是最干净的。

    【讨论】:

    • 感谢您帮我检查。我花了很多时间试图找出问题所在。看来我的编译器出了点问题...
    • 感谢您的接受,但我认为您正在得出关于您的编译器“错误”的结论。我认为这种行为是“未定义”的。遵循我为确保 result 被初始化为合理的东西而提出的建议之一(正如其他答案也指出的那样) - 不要只责怪你的编译器!
    • 是的,我试过了,但事实并非如此。我稍后在 main() 函数中有一个 while(1) {} 循环,由于某种原因,它导致输出卡住,即使输出代码在循环之前和之外。非常感谢!
    • 啊...臭名昭著的“其他代码”。这就是为什么总是建议您将问题作为重现问题的小型、独立、完整的程序提出。好吧,我很高兴你知道了!
    猜你喜欢
    • 2011-08-16
    • 1970-01-01
    • 2016-07-21
    • 2018-11-29
    • 2016-07-30
    • 2018-02-07
    • 2016-01-21
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多