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



快速前提:由于这个问题,我解决了我想做的事情,但我仍然想了解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, &len, my_file)) != -1)
{
my_struct->value2 = line;
}
else
perror("Error reading line of file");
if ((line_out = getline(&line, &len, my_file)) != -1)
{
my_struct->value3 = atof(line);
}
else
perror("Error reading line of file");
if ((line_out = getline(&line, &len, my_file)) != -1)
{

my_struct->value4 = line;
}
else
perror("Error reading line of file");
fclose(my_file);
}

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

value1: 11
value2: beta
value3: 23.450000
value4: beta
所以有两个问题:line"指针指向指针"(对吧?)似乎跳转到下一个位置并影响前一个条目(这是可以理解的,但我不确定在不创建新变量的情况下如何避免这种情况),并且在字符串末尾添加了n,我不知道它来自哪里。

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

void myFunct(char *my_file_path, struct myStruct *my_struct)
{
FILE *my_file = fopen(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, &len, my_file)) != -1)
{
my_struct->value1 = atoi(line);
}
else
perror("Error reading line of file");
if ((line_out = getline(&line2, &len, my_file)) != -1)
{
line2[strlen(line2) - 1]  = '';
my_struct->value2 = line2;
}
else
perror("Error reading line of file");
if ((line_out = getline(&line, &len, my_file)) != -1)
{
my_struct->value3 = atof(line);
}
else
perror("Error reading line of file");
if ((line_out = getline(&line4, &len, my_file)) != -1)
{

line4[strlen(line4) - 1]  = '';
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()文档中说得很清楚:

缓冲区以空结束,如果找到换行符,则包含换行符。

这就像fgets()。你可以很容易地删除它:

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

相关内容

最新更新