用C替换文本文件中的行

用C替换文本文件中的行,c,printf,scanf,fgets,C,Printf,Scanf,Fgets,我有一个需要修改的配置文件 该文件的结构是: resolution 12x34 interval 1234 所以两个带空格分隔符的字符串。我用来修改它的代码如下: FILE *fp = fopen(configuration_file, "a+"); char str[100], key[100], value[100]; if(fp) { while(fgets(str, 100, fp) != NULL) { if(2 == sscanf(str, "%s %s",

我有一个需要修改的配置文件

该文件的结构是:

resolution 12x34
interval 1234
所以两个带空格分隔符的字符串。我用来修改它的代码如下:

FILE *fp = fopen(configuration_file, "a+");
char str[100], key[100], value[100];
if(fp) {
    while(fgets(str, 100, fp) != NULL) {
        if(2 == sscanf(str, "%s %s", &key, &value)) {
            if(strcmp(key, "resolution") == 0){
                if(msg->resolution){
                    fprintf(fp, "%s %s\r\n", key, msg->resolution);
                }
            } else if(strcmp(key, "interval") == 0) {
                if(msg->interval) {
                    fprintf(fp, "%s %d\r\n", key, msg->interval);
                }
            } else {
                fputs(str, fp);
            } 
        } else {
            fputs(str, fp);
        }
    }
} else {
    (void)printf("-- Configuration file not found (%s)\r\n --", configuration_file);
}
fclose(fp);
想法是逐行阅读。根据
fgets
的文档,它在换行时停止。字符串扫描每行并将它们解析为键和值。到目前为止一切顺利,一切如期。然后将新行打印到文件中,覆盖刚刚扫描的行。这就是问题所在。如果使用
fprintf
,则只处理第一个值,即分辨率。其结果是:

resolution oldxres
resolution newxres
它会覆盖错误的行,并完全跳过第二行

如果我删除
fprintf
,而只是打印找到的值,它会按预期打印这两个值

我错过了什么?
fprintf
是否推动文件指针

然后将新行打印到文件中,覆盖刚刚扫描的行

文件不是这样工作的。写入新文件。完成后,将新文件重命名为旧名称。或者,将整个文件读入内存,更改内存中的内容,然后将其写回

如果修改的行永远不会比原始行长,则可以重写单个行。否则,修改后的行将溢出下一行,并将其销毁。为了防止这种情况发生,您需要某种前瞻性缓冲区,这种缓冲区过于繁琐且容易出错。在最坏的情况下,您仍然需要读取整个文件

然后将新行打印到文件中,覆盖刚刚扫描的行

文件不是这样工作的。写入新文件。完成后,将新文件重命名为旧名称。或者,将整个文件读入内存,更改内存中的内容,然后将其写回


如果修改的行永远不会比原始行长,则可以重写单个行。否则,修改后的行将溢出下一行,并将其销毁。为了防止这种情况发生,您需要某种前瞻性缓冲区,这种缓冲区过于繁琐且容易出错。在最坏的情况下,您仍然需要读取整个文件。

a+
rw
不同。还有更多错误。在
fgets
之后,您必须(当然!)将文件指针倒回行的开头。当然,新行的长度必须与旧行的长度完全相同。因此,将
12x34
替换为
123x456
永远不会起作用,因为它将覆盖下一步的开头line@PaulOgilvie谢谢你的建议。不知道您必须倒带文件指针,或者行的长度必须完全相同。
a+
rw
不同。还有更多错误。在
fgets
之后,您必须(当然!)将文件指针倒回行的开头。当然,新行的长度必须与旧行的长度完全相同。因此,将
12x34
替换为
123x456
永远不会起作用,因为它将覆盖下一步的开头line@PaulOgilvie谢谢你的建议。没有意识到你必须倒带文件指针,或者行的长度必须完全相同。没有想到修改后的行的长度,因此现在感觉有点愚蠢。这不是一个好办法。谢谢你的建议。工作很有魅力!没想到修改线的长度,后来觉得现在有点傻。这不是一个好办法。谢谢你的建议。工作很有魅力!