【问题标题】:How to replace a character in text file using C?如何使用C替换文本文件中的字符?
【发布时间】:2022-01-08 11:42:45
【问题描述】:

我需要读取一个文本文件 (E3-5.txt),然后搜索要替换为 c2 的字符 c1。 这是我的不完整代码:

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

int main()
{
    char c;
    char c1 = 'm';
    char c2 = 'a';
    int i;
    FILE* fp;
    fp = fopen("C:\\E3-5.txt", "r+");
    if (fp == NULL)
    {
        printf("File not found!");
        return 0;
    }
    for(c = getc(fp); c != EOF; c = getc(fp))
    {
        if(c == 'm')
        {
            i = ftell(fp);
            printf("\nPosition %d", i);
        }

    }
}

我在如何定位 c1 在文本中的位置以及如何重写它时遇到了麻烦。 编辑: 我使用了答案中的代码,但它没有改变文本。 这是新代码:

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

int main()
{
    char c;
    char c1 = 'm';
    char c2 = 'a';
    int i;
    FILE* fp;
    fp = fopen("C:\\E3-5.txt", "rb+");
    if (fp == NULL)
    {
        printf("File not found!");
        return 0;
    }
    else
    {
        for(c = getc(fp); c != EOF; c = fgetc(fp))
        {
            if(c == c1)
            {
                fseek(fp, -1, SEEK_CUR);
                fputc(c2, fp);
            }
            else
            {
                return 0;
            }
        }
    }
   return 0;
}

程序返回0,文本中没有写任何东西

【问题讨论】:

  • 因为它是用rb+打开的窗口

标签: c file fopen


【解决方案1】:

字符串替换

为了完整起见,这里有一些代码来替换文件中的单词!这将替换单个字符,因此它当然会回答问题并显示一些有用的示例。

这也是我的第一个也是唯一一个非平凡的黄金程序,写于 1994 年 5 月!尽管您当然可以找到它的错误,但它按预期工作,我和我的同事以许多不同的方式使用它来完成与系统管理员相关的任务。在 MS C/C++ 上编译

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

#define err(e) {_fcloseall(); fprintf(stderr,        \
           "USAGE: chg source dest oldstr newstr\n%s\n",e); exit(1);}

main (int argc,char *argv[])
{
    FILE *in,*out;
    char buffer[200];
    char *old,*new;
    int i,j,k;


    if (argc!=5)
        err("invalid # of parameters");
    if ((in=fopen(argv[1],"r"))==NULL)
        err("Can't open source");
    if ((out=fopen(argv[2],"w"))==NULL)
        err("Can't open dest");
    old=argv[3];
    new=argv[4];
    if (*old=='"')
        old++;
    if (*new=='"')
        new++;
    if (i=strlen(old) && old[i-1]=='"')
        old[i-1]=0;
    if (i=strlen(new) && new[i-1]=='"')
        new[i-1]=0;
    if (!*old)
        err("Can't search for nothing!");
    if (!*new)
        err("Can't replace nothing!");
    j=0;
    while (!feof(in))
    {
        if ((buffer[j]=fgetc(in))==EOF)
            break;
        buffer[j+1]=0;
        j++;
        if (!old[j-1])
        {
            fprintf(out,new);
            fputc(buffer[j-1],out);
            j=0;
        }
        else if (_strnicmp(buffer,old,j))
        {
            fprintf(out,buffer);
            j=0;
        }
        else if (j>195)
            err("Internal error, buffer filled past 195");
    }
}

【讨论】:

    【解决方案2】:

    您真的不想直接操作文件。曾经。这样做只是要求数据损坏。相反,创建一个新文件并在完成后移动它。此外,编写代码要容易得多。你可以这样做:

    #include <stdio.h>
    #include <unistd.h>
    
    int
    main(int argc, char **argv)
    {
        int c1 = argc > 1 ? argv[1][0] : 'm';
        int c2 = argc > 2 ? argv[2][0] : 'a';
        const char *path = argc > 3 ? argv[3] : "stdin";
        FILE *in = argc > 3 ? fopen(path, "r") : stdin;
        if( in == NULL ){
            perror(path);
            return 1;
        }
        FILE *out = stdout;
        char tmp[1024] = ".tmpXXXXX";
        char *outpath = "stdout";
        if( argc > 3 ){
            outpath = tmp;
            int fd = mkstemp(tmp);
            if( fd == -1 ){
                perror("mkstemp");
                return 1;
            }
            if( (out = fdopen(fd, "w")) == NULL ){
                perror(tmp);
                return 1;
            }
        }
        int c;
        while( (c = fgetc(in)) != EOF ){
            if( c == c1 ){
                c = c2;
            }
            if( fputc(c, out) == EOF ){
                perror(outpath);
                return 1;
            }
        }
        if( argc > 3 ){
            if( fclose(out) ){
                perror(outpath);
                return 1;
            }
            if( rename(outpath, path) ){
                perror(path);
                return 1;
            }
        }
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      getc() 返回 int,因此您需要声明 int c 而不是 char c 以检查 EOF。

      ftell() 获取位置。使用fwrite()fputc() 通过设置fseek() 写入该位置的文件。

      转至https://en.cppreference.com/w/c 以供参考。许多初学者无法阅读所有标准库函数,有些甚至重新发明轮子。

      【讨论】:

      • 我不认为这是问题所在,因为我在之前的代码中多次使用了char c,而且效果很好。
      • 这是在滥用未定义的行为。
      • @MariaMarchellaGandhi 所以你过去多次犯过同样的错误。了解未定义的行为。
      【解决方案4】:

      这里有一个非常幼稚的:

      int freplace(FILE *f, char needle, char repl)
      {
          int result = 1;
          int c;
          if(f)
          {
              while((c = fgetc(f)) != EOF)
              {
                  if(c == needle)
                  {
                      fseek(f, -1, SEEK_CUR);
                      fputc(repl, f);
                      //all I/O functions require error handling
                  }
              }
          }
          return result;
      }
      

      【讨论】:

      • 嗨,我编辑了这个问题。
      猜你喜欢
      • 1970-01-01
      • 2021-02-08
      • 2017-12-05
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 2014-01-01
      相关资源
      最近更新 更多