【问题标题】:C: Delete all occurrences of a word in a fileC:删除文件中所有出现的单词
【发布时间】:2015-12-15 19:34:53
【问题描述】:

我需要从标准输入读取一个字符串,然后删除文件中该字符串的所有出现。我必须覆盖原始文件。下面我发布我到目前为止的源代码。它的问题是我不知道应该为while 循环添加什么停止条件,以及如何覆盖原始文件? (如您所见,我尝试将所有不等于给定字符串的单词添加到单独的文件中)。

#include <stdio.h>
#include <string.h>

int main()
{
    FILE *fp, *fp_out;
    char s[50], del[50];

    fp = fopen("file_in", "r");
    fp_out = fopen("file_out", "a");

    fgets(del, 50, stdin);
    fgets(s, 50, (FILE *)fp);

    while(s != EOF) //I know that this does not work, what condition should I add?
    {
        fgets(s, 50, (FILE *)fp);
        if(strcmp(s, del) != 0)
            fprintf(fp_out, "%s ", s);
    }

    fclose(fp);
    fclose(fp_out);

    return 0;
}

我提到我也尝试添加while(s != NULL),但这会创建一个 592 MB 的文本文件,其中包含我输入文本文件中的所有单词。

【问题讨论】:

  • 您不会覆盖原始文件,因为您会在尝试读取它的同时杀死它。您创建一个新的临时文件,将您的复制/过滤到该临时文件中。然后你删除原始文件并重命名临时文件。
  • 你想要的循环是这样的:while (fgets(s, 50, fp))。要了解原因,请查看fgets return value。另外,在fp 上搭便车。它已经是 FILE *,所以没有理由投射它。
  • 您正在丢弃输入文件的第一行,这意味着您在读取第二行之前不处理它。
  • 如果要删除的词是“abca”,文件是“abcabca”,应该保留什么? “bca”还是“”?
  • ...或“abc”应该保留吗?

标签: c string file input


【解决方案1】:

您的 while 条件可以是:

 while(fgets(s, sizeof s, fp)) {

 }

fgets() 在到达文件末尾或出错时返回 NULL。另外,请注意fgets() 会将换行符读入缓冲区,如果有空间,您可能希望在字符串比较之前将其删除。请注意,转换为FILE* 是多余的。

要删除换行符,如果有的话,你可以使用strchr()

char *p = strchr(del, '\n');
if(p) *p = '\0';

然而,

1) 您正在将整行(由fgets() 读取)与您从stdin 读取的单词 进行比较。因此,如果行中有多个单词,则此替换将不起作用。因此,您可能需要将行拆分为单词,然后使用另一个循环来比较行中的每个单词。

2) 您没有覆盖同一个文件。所以你可以在所有替换结束时使用rename()来覆盖原始文件。

【讨论】:

  • 删除原始文件必须在重命名之前。
  • 终于我明白你在告诉我什么:我应该使用strtok' ' 分隔符将(最多)50 个字符长的字符串分成单词,然后比较每个人带有我从标准输入读取的字符串的单词。我说的对吗?
  • @CareyGregory 除非存在权限问题、无效路径等rename 会删除旧文件。
  • @Polb 是的,这是一种方式。但请注意,strtok() 不是可重入的,如果单词有不同的空格(例如制表符、换行符等),您可能需要使用的不仅仅是 ' '
  • @l3x rename 将覆盖 some 平台和 some 实现上的现有文件,但不能保证。删除然后重命名保证在所有情况下都有效(假设没有权限问题)。
猜你喜欢
  • 2018-06-15
  • 2017-11-01
  • 2016-02-02
  • 2023-03-10
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
相关资源
最近更新 更多