在C中读取文件:“r”和“a +”标志的不同行为

我想打开一个文件,读取其内容,然后在文件中附加一行。 我以为我应该使用“a +”标志来完成任务。

我有一个打开文件并返回指向该文件的指针的函数。

FILE* open_weekly_disk_file(char* filename){ FILE* weekly_log; weekly_log = fopen(filename, "a+"); //weekly_log = fopen(filename, "r"); if(! weekly_log){ printf("The attempt to open the weekly log failed!\n"); return NULL; } else{ return weekly_log; } } 

然后我有一个函数调用上面的函数并使用scanf从文件中读取内容:

 void sample_function(char* filename){ FILE* log; char token[100], current_read[100]; int limit; log = opened_weekly_disk_file(filename); // The problem happens here for(limit=0; limit < TOKEN_NUMBER; limit++){ if(fscanf(log, "%s%s", &token, &current_read) == 2){ printf("%s %s\n", token, current_read); } } ... } 

我使用时此代码有效:

 weekly_log = fopen(filename, "r"); 

但是当我将“r”标志更改为“a +”时不起作用。 我在for循环之前得到了一个Segmentation错误。

这是因为模式规范"a"打开一个文件以便追加,文件指针在末尾。 如果您尝试从此处读取,则由于文件指针位于EOF,因此没有数据。 您应该打开"r+"进行阅读和写作。 如果在写入之前读取整个文件,则在写入更多数据时,文件指针将正确定位以追加。

如果这还不够,请探索ftell()fseek()函数。

从这个SO QA

从手册页:a +

打开阅读和追加(在文件末尾写)。 如果文件不存在,则创建该文件。 用于读取的初始文件位置位于文件的开头,但输出始终附加到文件的末尾。

回答:

只有一个指针最初位于文件的开头,但是当尝试写入操作时,它会移动到文件的末尾。 您可以使用fseek重新定位它或在文件中的任何位置重绕以进行读取,但写入操作会将其移回文件末尾。

因此,问题在于文件是以附加模式打开的,因为就读取而言,它并非如此。

问题在于你的代码在这三个点中的作用

 log = opened_weekly_disk_file(filename); ... 

代码很可能写入文件,使文件光标在读取发生之前移动到它的末尾。