代码之家  ›  专栏  ›  技术社区  ›  Kagemand Andersen

用C替换文本文件中的行

  •  0
  • Kagemand Andersen  · 技术社区  · 7 年前

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

    文件结构为:

    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。其结果是:

    resolution oldxres
    resolution newxres
    

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

    如果我删除 格式化输出 而不是简单地打印找到的值,而是按预期打印这两个值。

    我错过了什么?做 格式化输出 推送文件指针?

    1 回复  |  直到 7 年前
        1
  •  2
  •   n. m. could be an AI    7 年前

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

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

    如果修改的行从未超过原始行,则可以重写单个行。否则,修改后的行将溢出到您尚未阅读的下一行,并将其销毁。为了防止这种情况发生,您需要某种前瞻缓冲区,这种缓冲区过于繁琐且容易出错。在最坏的情况下,您无论如何都需要读取整个文件。