微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C - 使用 getline() 从文本文件中读取的字符指针为什么会发生这种情况?如何改进我的解决方法?

如何解决C - 使用 getline() 从文本文件中读取的字符指针为什么会发生这种情况?如何改进我的解决方法?

快速前提:由于 this 问题,我解决了我想做的事情,但我仍然想了解 C 在这种情况下的工作原理。

我有一个类似于这个的纯文本文件(我们称之为 my_file):

11
alpha
23.45
beta

我在 .c 文件中编写了一个函数,该函数读取该文件的每一行并根据我创建的自定义 struct 存储所有这些值。假设它是:

struct myStruct
{
    int value1;
    char *value2;
    double value3
    char *value4;
} my_struct;

这是我写的函数(不工作):

void myFunct(char *my_file_path,struct myStruct *my_struct)
{
    FILE *my_file = fopen(my_file_path,"r");
    int line_out;
    char *line = NULL;
    size_t len = 0;

    if (my_file == NULL)
    {
        perror("Could not open file");
    }

    if ((line_out = getline(&line,&len,my_file)) != -1)
    {
        my_struct->value1 = atoi(line);
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line,my_file)) != -1)
    {
        my_struct->value2 = line;
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line,my_file)) != -1)
    {
        my_struct->value3 = atof(line);
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line,my_file)) != -1)
    {
    
        my_struct->value4 = line;
    }
    else
        perror("Error reading line of file");

    fclose(my_file);
}

注意我将结构体实例作为指针传递。 也就是说,调用函数会产生以下结果(通过 printf 的终端输出):

value1: 11
value2: beta

value3: 23.450000
value4: beta

所以有两个问题:line“指向指针的指针”(对吗?)似乎跳到下一个位置并影响上一个条目(这是可以理解的,但我不确定如何避免这种情况没有创建新变量),并且在字符串末尾添加一个 \n,我不知道它来自哪里。

我不明白这一般是如何工作的,我也想知道一些聪明的想法来解决这个问题。 如果有人需要它(但回复中肯定会有更好的解决方案),我已将我的功能修改如下:

void myFunct(char *my_file_path,"r");
    int line_out;
    char *line = NULL;
    char *line2 = NULL;
    char *line4 = NULL;
    size_t len = 0;

    if (my_file == NULL)
    {
        perror("Could not open file");
    }

    if ((line_out = getline(&line,my_file)) != -1)
    {
        my_struct->value1 = atoi(line);
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line2,my_file)) != -1)
    {
        line2[strlen(line2) - 1]  = '\0';
        my_struct->value2 = line2;
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line,my_file)) != -1)
    {
        my_struct->value3 = atof(line);
    }
    else
        perror("Error reading line of file");

    if ((line_out = getline(&line4,my_file)) != -1)
    {
    
        line4[strlen(line4) - 1]  = '\0';
        my_struct->value4 = line4;
    }
    else
        perror("Error reading line of file");

    fclose(my_file);
}

这不是很可扩展,但可以完成工作。

感谢您的帮助!

解决方法

getline() 仅在 line 参数指向空指针或未指向足够空间时才分配新行缓冲区。否则,它会重用传递给它的相同缓冲区。所以每次你这样做

my_struct->something = line;

您可能正在保存指向同一字符串的指针。

使用 strdup() 复制字符串。

my_struct->something = strdup(line);

不要忘记在函数的末尾加上 free(line),因为制作这些副本时不再需要它。

字符串末尾的 \n 是结束用户输入的换行符。它在 getline() documentation:

中清楚地说明了这一点

缓冲区以空字符结尾并包含换行符(如果找到的话)。

这就像fgets()。您可以轻松删除它:

if (line[strlen(line)-1] == '\n') {
    line[strlen(line)-1] = '\0';
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。