1

C 新手,我正在尝试就地进行文本替换。我认为 fopen 中的 r+ 应该允许我读写。我正在查看文件中的每一行,如果它以 / 开头,那么我将http://example.com附加到该行的开头。Example...line is /tree 然后该行变为http://example.com/tree。正则表达式工作正常。我可以很好地读取文件,但它没有写入。任何想法为什么?

void
fix_relative (char *page)
{
  FILE *fp;
  fp = fopen ("file", "r+");

  char line[1000];
  regex_t re;
  regcomp (&re, "^/", REG_EXTENDED);

  while (fgets (line, sizeof line, fp) != NULL)
    {
      if (regexec (&re, line, 0, NULL, 0) == 0) {
    fprintf (fp, "http://example.com%s\n", line);
      }
    }

  fclose (fp);
}
4

3 回答 3

2

这可以帮助您了解您的问题

fopen 函数

目的:打开一个流。更安全的 fopen_s 函数也可用。

语法:FILE * fopen(const char *name, const char *mode);

声明于:

fopen 函数打开名称为 name 指向的字符串的文件,并将流与它关联。该字符串可能包含完整路径(从根目录开始)、相对路径(从当前目录开始)或只是一个名称。

参数模式指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。

  • "r" 打开文本文件进行阅读。
  • "w" 截断到零长度或创建文本文件进行写入。
  • “一”附加;打开或创建文本文件以在文件末尾写入。
  • "rb" 打开二进制文件进行读取。
  • "wb" 截断为零长度或创建二进制文件进行写入。
  • “ab” 附加;打开或创建二进制文件以在文件末尾写入。
  • "r+" 打开文本文件进行更新(读取和写入)。
  • "w+" 截断为零长度或创建文本文件进行更新。
  • "a+" 追加;打开或创建文本文件以进行更新,在文件末尾写入。
  • "rb+" 打开二进制文件进行更新(读取和写入)。
  • "wb+" 截断为零长度或创建二进制文件进行更新。
  • "ab+" 追加;打开或创建二进制文件以进行更新,在文件末尾写入。
  • "r+b" 与 "rb+" 相同
  • "w+b" 与 "wb+" 相同
  • "a+b" 与 "ab+" 相同

如果文件不存在或无法读取,则以读取模式(“r”作为模式参数中的第一个字符)打开文件将失败。

使用附加模式(“a”作为模式参数中的第一个字符)打开文件会导致所有后续对该文件的写入都被强制到当时的当前文件结尾,而不管对 fseek 函数的干预调用。

当文件以更新模式打开时(“+”作为模式参数中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,如果没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的干预调用,则输出不应直接跟随输入,并且在没有对文件定位的干预调用的情况下,输入不应直接跟随输出函数,除非输入操作遇到文件结尾。

打开时,如果且仅可以确定流中的一个流不引用交互式设备,则流是完全缓冲的。流的错误和文件结束指示符被清除。

返回: 指向成功时控制流的对象的指针,否则为空指针。

于 2013-07-20T14:10:01.523 回答
2

这怎么可能行不通。只要您的新字符串与原始字符串不完全一样长,您就会遇到问题。此外,由于您在文本模式下工作,因此可能会因为换行符/回车符翻译而产生额外的伪影。

相反,请执行以下操作:

  • 打开文件“文件”只读
  • 创建一个仅用于写入的新临时文件
  • 读取一行,必要时修改,写入新文件
  • 完成后,删除“文件”并重命名您的临时文件。
于 2013-07-20T14:16:37.113 回答
1

可能不清楚的一件事:如果您更新文件中的行,并且您的替换文本的长度与它正在替换的内容不完全相同,您将对文件进行完整的哈希:您将覆盖它之后的内容.

因此,如果您有一个包含以下句子的文件:

   I love programming.
   I love life.

并且您将文件位置设置为第一句并将“love”替换为“loathe”,您将不会得到

   I loathe programming
   I love life

你会得到

   I loathe programming love life

因为您现在已经覆盖了第一句中的行分隔符,以及下一句中的“I”。

如果用更长的字符串替换字符串,则会将文件中的所有其他字符向前推。要进行替换,您必须将整个文件读入内存,进行替换,然后将文件写回磁盘。

于 2013-07-20T14:18:59.303 回答