2010-08-09 139 views
0

问题是查找并替换C文件中的字符串在C文件中查找并替换

我是C文件新手。我曾尝试下面的代码,但我没有得到任何输出:

#include<stdio.h> 
    #include<string.h> 
    int main() 
    { 
     FILE *f1,*f2; 
     char *src,*dest,*s1,ch,ch1,ch2,ch3; 
     int i; 
     f1=fopen("input.txt","rw"); 
     f2=fopen("dummy.txt","rw"); 
     src="mor"; 
     dest="even"; 
     while(ch!=EOF) 
     { 
     ch=fgetc(f1); 
     if(ch==src[0])      //Finding 1st char of src 
     { 
     fgets(s1,strlen(src),f1); 
     if(strcmp(src+1,s1)==0)   //Finding occurance of "src" in file 
     { 
      fseek(f1,strlen(src)-1,SEEK_CUR); 
      while(ch1!=EOF)    //Copying remaining data into another file 
      { 
      ch1=fgetc(f1); 
      fputc(ch1,f2); 
      } 
     fseek(f1,-strlen(src),SEEK_CUR); 
     for(i=0;i<strlen(dest);i++) //replacing "src" with "dest" 
     { 
      ch2=dest[i]; 
      fputc(ch2,f1); 
     } 
     fclose(f1); 
     f1=fopen("input.txt","a"); 
     while(ch3!=EOF)  //Appending previosly copied data into 1st file 
     { 
      ch3=fgetc(f2); 
      fputc(ch3,f1); 
     } 
    } 
    } 
} 
    fclose(f1); 
    fclose(f2); 
} 

input.txt中的内容是“早晨”。

请指出逻辑中的错误,并给出相同的有效代码。

在此先感谢。

+2

最明显有效的代码会是这样的:'sed的 “S /源/目标/ G” input.txt'。直接用C做这件事并没有什么意义(至少在我看来)。 – 2010-08-09 15:14:28

+2

@Jerry Coffin ...先生,但问题是要测试我们对使用C文件的理解! – 2010-08-09 15:21:52

+0

“这个问题被要求测试我们对使用C文件的理解” - 这是一个家庭作业问题吗?如果是这样,您可能需要添加“作业”标签。 – 2010-08-10 05:38:04

回答

3

在C中读取文件通常有点混乱。我看到的第一个问题是ch在主循环中的使用方式。第一次执行

while (ch != EOF) 

,CH是未初始化的,如果碰巧持有EOF,主循环将根本不执行。我通常用以下结构从文件中读取:

FILE *fInput = fopen("input.txt", "r"); 
int ch; /* need an int to hold EOF */ 

for (;;) 
{ 
    ch = fgetc(fInput); 
    if (ch == EOF) break; 

    ... 
} 

另外,你可能需要在文件指针的概念读了。例如,在读取src的其余部分后,您将fseek()转发,并在将数据复制到f2之前跳过更多字符。本质上,你读m,读or(与fgets() - 并进入一个未分配的缓冲区s1,这将在不久的将来有一段时间ka-boom),再跳过2个字符(现在你的指针是在“早晨” ),将“ng”复制到f2中,尝试在此循环中将EOF写入f2(因此上述读取模式直到EOF),寻找两个字符(一旦达到EOF就可能失败,我的C文件功能有点生锈这些日子)​​,写“甚至”到f1(如果我在EOF之后寻找错误,请将输入文件设置为“mornieven”,并且如果我正确的话不要更改它)。总之,我认为代码不会做你打算做的事情。

我会建议建立你的功能。下面的每一个可以写成你应该才去下一步测试和完成的程序:

  1. 读取安全文件,并打印出来
  2. 检测src内容,并打印输入
  3. 的其余部分保存输入到第二个文件,其余的不是打印
  4. 在第一文件dest替换src,而忽略其他(因为你打开输入文件“RW”,这将截断的休息输入)。您可能需要执行fseek()来清除EOF状态。另外,也要看看ftell()记录,你可以跳回到使用fseek()
  5. 最后一个位置,复制一切,你有dest(无需更换src在这里收F1后保存到第二个文件,但最好是打开F2作为写入,从第一个文件复制后关闭,然后重新打开以执行复制回f1)。

此外,当你需要一个缓冲(如S1),只需使用一个足够大的数组了,但考虑malloc()free()函数来执行动态内存分配这样的情形。

+0

非常感谢您分析整件事的努力。我不能够感谢你。在找到“src”后,我使用了fseek,我不知道fgets移动文件指针。我应该更好地阅读这些概念。所以,如果这件事情得到照顾,该程序做我打算做的对吗? 我也会尝试U给的方法......再次感谢!!!! – 2010-08-10 15:00:51

1

您在输出中打印错误的东西。打印“ch”,而不是文件指针。

 
while(ch!=EOF) 
{ 
    ch=getc(f1); 
    printf("%c",ch); 
} 
while(ch!=EOF) 
{ 
    ch=getc(f2); 
    printf("%c",ch); 
} 

此外,f2在输出过程结束时关闭。你将不得不重新打开它(就像你与F1做的。)

+0

@Starsky,我有你的点先生。我在代码中改变了它。 我已经删除了打印部分。 请检查替换逻辑中的任何错误先生。该input.txt的文件将不会得到改变上运行,并且原始内容将保留....感谢乌拉圭回合的帮助爵士...... – 2010-08-09 15:24:08

2

一种简单的方法做替代将是在整个文件中第一次读入缓冲区

例如

FILE* fpIn = fopen("file.txt","rb"); 
fseek(fpIn, 0L, SEEK_END); 
size_t s = ftell(fpIn); 
fseek(fpIn, 0L, SEEK_SET); 
void* buf = malloc(s); 
fread(buf,s,1,fpIn); 

现在在写文件,检查您的字符串

char src[] = "mor"; 
char dest[] = "even"; 
int lenSrc = strlen(src); 
int lenDest = strlen(dest); 
for (char* ch = buf; ch < buf + s; ++ch) 
{ 
    if (!memcmp(ch, src, lenSrc)) 
    { 
    fwrite(dest, 1,lenDest, fpOut); 
    ch += lenSrc; 
    } 
    else 
    { 
    fputc(*ch, fp); 
    } 
} 

免责声明:没有编制本

+0

@Andres K,非常感谢先生......我会尽力ü给先生的方法,我认为这比搜索和替换文件更容易! – 2010-08-10 15:03:11

1

乍一看,我看你的代码中调用与fgets是错误的。您尚未分配任何内存,并且正在将字符串读入未初始化的指针。读入数组或动态分配的内存。

+0

就像你指出的,fgets似乎没有问题。它编译罚款和执行正确..我将其读入其中previosly宣布..... – 2010-08-09 15:45:35

+1

@Shyam你的'fgets'是不正确的字符串。 's1'不是一个字符串,它是一个指向字符数组的指针,它是未经过初始化的。您正在写入未分配的内存。这不是编译错误;这是一个更严重的逻辑错误,会导致未定义的行为。 – meagar 2010-08-09 17:00:30

+0

@meager .... s1未初始化,逻辑上它不正确..我知道tat。但由于我没有得到任何的错误,所以我会保持原样。能否检查我在程序中使用的逻辑中的任何错误。 Thnaks – 2010-08-10 14:52:30

1

另一个问题是,您声明chcharfgetc()返回int,并有很好的理由。这是好事,可以返回任何可能的字符或EOF,所以EOF不应该是一个角色,所以理想fgetc()返回比char更大的类型。

结果是循环可能永远不会结束,因为ch在某些标准实现上不可能保存EOF。声明它(ch1ch3)为int