我正在尝试从C语言的文件中删除一个单词

我正在尝试从C语言的文件中删除一个单词,c,C,我编写了一个程序,从文件中删除某个单词(作为用户输入)。我读单词,打开我想删除单词的文件,阅读文件中的每一行并将其拆分为单词,然后将每个单词与我的关键字进行比较。如果它们不匹配,我会将它们打印到一个临时文件中 但是当我打开临时文件时,整个文本都被复制了。有人能帮我吗 #include<stdio.h> #include<fcntl.h> #include<string.h> main() { int i; FILE *fp1,*fp2; char key[1

我编写了一个程序,从文件中删除某个单词(作为用户输入)。我读单词,打开我想删除单词的文件,阅读文件中的每一行并将其拆分为单词,然后将每个单词与我的关键字进行比较。如果它们不匹配,我会将它们打印到一个临时文件中

但是当我打开临时文件时,整个文本都被复制了。有人能帮我吗

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

main()
{
int i;
FILE *fp1,*fp2;
char key[1000],a[1000],temp[1000];

printf("\nEnter the word to be deleted from file : ");
scanf("%s",key);

fp1 = fopen("a.txt","r");
fp2 = fopen("b.txt","w");

while(fgets(a,1000,fp1))
{
    for(i=0;a[i]!='\0';++i)

        if(a[i]==' ')
            break;
        else            
            temp[i]=a[i];
    temp[i]='\0';
    if(strcmp(temp,key)!=0)
    {
        fputs(temp,fp2);
    }

    bzero(a,1000);
}

fclose(fp1);
fclose(fp2);

printf("\n\n");

/*remove("a.txt");
rename("b.txt","a.txt");*/

}
#包括
#包括
#包括
main()
{
int i;
文件*fp1,*fp2;
字符键[1000],a[1000],温度[1000];
printf(“\n输入要从文件中删除的单词:”;
scanf(“%s”,键);
fp1=fopen(“a.txt”,“r”);
fp2=fopen(“b.txt”,“w”);
而(fgets(a、1000、fp1))
{
对于(i=0;a[i]!='\0';++i)
如果(a[i]=='')
打破
其他的
温度[i]=a[i];
温度[i]='\0';
如果(strcmp(温度、钥匙)!=0)
{
FPUT(温度,fp2);
}
b0(a,1000);
}
fclose(fp1);
fclose(fp2);
printf(“\n\n”);
/*删除(“a.txt”);
重命名(“b.txt”、“a.txt”)*/
}

问题的一部分是,一旦找到一个空格,您就可以处理该单词,但没有完成对该行其余部分的处理。在FPUT之后,您转到循环的顶部并读取另一行。当我编译并运行您的代码段时,它确实会输出每行的第一个单词,只要它不是选定的单词

此外,在输出单词时,不会输出单词之间的任何空格,并且在行尾没有回车符。因此,所有不匹配的字在一行上背靠背输出

下面的代码片段还修复了一些问题(还有一些我没有解决的问题——例如,如果行上没有尾随空格,则不会输出行上最后一个不匹配的字。您可以通过查找“\0”和空格来解决此问题。我没有这样做,因为它要求在看到“\0”时将循环结构更改为不退出,这样您就有机会对其进行测试):


问题的一部分是,一旦找到一个空格,您就处理该单词,但您没有完成对该行其余部分的处理。在FPUT之后,您转到循环的顶部并读取另一行。当我编译并运行您的代码段时,它确实会输出每行的第一个单词,只要它不是选定的单词

此外,在输出单词时,它们之间不输出任何空格,并且在行尾没有回车符。因此,所有不匹配的单词都在一行上背靠背输出

下面的代码片段还修复了一些问题(还有一些我没有解决的问题——例如,如果行上没有尾随空格,则不会输出行上最后一个不匹配的字。您可以通过查找“\0”和空格来解决此问题。我没有这样做,因为它要求在看到“\0”时将循环结构更改为不退出,这样您就有机会对其进行测试):


尝试编译它,但除了在输出文件中不插入空格外,它几乎可以正常工作;)


另外,它的代码非常敏感。如果我有一行单词,它就不起作用。如果测试文件在word之前有空格,而关键字没有空格,它就不起作用。

尝试编译它,它几乎可以正常工作,只是它没有在输出文件中插入空格;)

而且,它的代码非常敏感。如果我有一行字就不行了。如果您的测试文件在word之前有空格,而您的关键字没有空格,那么它就不应该工作。

一些观察结果

main()
{
    //you will need input index, output index
    int in, on; //in: input index, on: output index
    FILE *fp1,*fp2;
    char key[1000],iray[1000],oray[1000];
    char* here; //clarifies the comparison

    printf("\nEnter the word to be deleted from file : ");
    scanf("%s",key);
    printf("key: %s",key); fflush(stdout);

    if(!(fp1 = fopen("a.txt","r"))) { printf("open error\n"); exit(1); }
    if(!(fp2 = fopen("b.txt","w"))) { printf("open error\n"); exit(2); }

    while(fgets(iray,sizeof(iray),fp1))
    {
        printf("line: %s",iray); fflush(stdout);
        for(in=on=0; iray[in]; ++in) //'\0' = 0 = false //please indent
        {   //please use braces
            //printf("%d: %c\n",in,iray[in]); fflush(stdout);
            if(iray[in]==' ')
            {
                oray[on++] = iray[in];
                continue; //break gets you out of loop
            }
            here = &(iray[in]);
            //printf("here: %s\n",here); fflush(stdout);
            if( !strcmp(here,key) ) //have word?
            {
                in+=strlen(key); //skip word
                continue;
            }
            oray[on++] = iray[in];
        }
        oray[on] = '\0';
        printf("line: %s",oray); fflush(stdout);
        fputs(oray,fp2);
        iray[0]=0; //bzero(iray,1000);
        oray[0]=0; //bzero(oray,1000);
    }
    fclose(fp1);
}
一些观察结果

main()
{
    //you will need input index, output index
    int in, on; //in: input index, on: output index
    FILE *fp1,*fp2;
    char key[1000],iray[1000],oray[1000];
    char* here; //clarifies the comparison

    printf("\nEnter the word to be deleted from file : ");
    scanf("%s",key);
    printf("key: %s",key); fflush(stdout);

    if(!(fp1 = fopen("a.txt","r"))) { printf("open error\n"); exit(1); }
    if(!(fp2 = fopen("b.txt","w"))) { printf("open error\n"); exit(2); }

    while(fgets(iray,sizeof(iray),fp1))
    {
        printf("line: %s",iray); fflush(stdout);
        for(in=on=0; iray[in]; ++in) //'\0' = 0 = false //please indent
        {   //please use braces
            //printf("%d: %c\n",in,iray[in]); fflush(stdout);
            if(iray[in]==' ')
            {
                oray[on++] = iray[in];
                continue; //break gets you out of loop
            }
            here = &(iray[in]);
            //printf("here: %s\n",here); fflush(stdout);
            if( !strcmp(here,key) ) //have word?
            {
                in+=strlen(key); //skip word
                continue;
            }
            oray[on++] = iray[in];
        }
        oray[on] = '\0';
        printf("line: %s",oray); fflush(stdout);
        fputs(oray,fp2);
        iray[0]=0; //bzero(iray,1000);
        oray[0]=0; //bzero(oray,1000);
    }
    fclose(fp1);
}

编辑:完整的解决方案: 以下是循环的外观:

while(fgets(a,1000,fp1))
{
  int j=0;
  for(i=0;a[i]!='\0';++i)
  {
    if(a[i]==' ')
    {
       temp[j]=0;
       if(strcmp(temp,key)!=0)
       {
          fputs(temp,fp2);
       }
       j=0;
       //this should be after fputs if you want to remove the space after obsolete word. 
        fputs(" ",fp2);         
    }
    else            
       temp[j++]=a[i];          
  }
  //last word if there is no space after!
  if(strcmp(temp,key)!=0)
  {
    fputs(temp,fp2);
  }
  fputs("\n",fp2);
  a[0] = 0;
}

编辑:完整的解决方案: 以下是循环的外观:

while(fgets(a,1000,fp1))
{
  int j=0;
  for(i=0;a[i]!='\0';++i)
  {
    if(a[i]==' ')
    {
       temp[j]=0;
       if(strcmp(temp,key)!=0)
       {
          fputs(temp,fp2);
       }
       j=0;
       //this should be after fputs if you want to remove the space after obsolete word. 
        fputs(" ",fp2);         
    }
    else            
       temp[j++]=a[i];          
  }
  //last word if there is no space after!
  if(strcmp(temp,key)!=0)
  {
    fputs(temp,fp2);
  }
  fputs("\n",fp2);
  a[0] = 0;
}

另一个解决方案。它有上面提到的一些相同的问题,例如一个单词的边界与英语语法不匹配。此外,在某些情况下,它的复制效率也很低,超出了严格必要的数量

但是,我更喜欢这个版本,因为它抽象了单词删除任务,而不是与代码的其余部分内联。而且效果更好

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

void remove_str2(char* buffer, char* find, int lfind) {
  char* paste = strstr(buffer, find);
  if (!paste) { return; }
  char* start = paste + lfind;

  while (1) {
    char* end = strstr(start, find);
    if (!end) {
      end = start + strlen(start) + 1;
    }
    memmove(paste, start, end - start);

    paste += end - start;
    start = strstr(end, find);
    if (!start) { return; }
    start += lfind;
  }
}

void remove_str(char* buffer, char* find, int lfind) {
  char* p = strstr(buffer, find);
  if (p) {
    remove_str(p + lfind, find, lfind);
    // shift everything left
    do { *p = *(p + lfind); } while (*(++p));
  }
}

int main() {
  FILE *fp1, *fp2;
  char key[1000], a[1000];

  // require key to be preceeded by a space
  key[0] = ' ';

  printf("\nEnter the word to be deleted from file : ");
  scanf("%s", &key[1]);

  fp1 = fopen("a.txt","r");
  fp2 = fopen("b.txt","w");

  while (fgets(a, 1000, fp1)) {
    remove_str(a, key, strlen(key));
    fputs(a, fp2);
  }

  fclose(fp1);
  fclose(fp2);

  printf("\n\n");

  return 0;
}
#包括
#包括
void remove_str2(字符*缓冲区、字符*查找、整数lfind){
char*paste=strstrstr(缓冲区,查找);
如果(!粘贴){return;}
char*start=paste+lfind;
而(1){
char*end=strstrstr(开始,查找);
如果(!结束){
结束=开始+strlen(开始)+1;
}
memmove(粘贴、开始、结束-开始);
粘贴+=结束-开始;
开始=strstr(结束,查找);
如果(!start){return;}
start+=lfind;
}
}
void remove_str(char*buffer、char*find、int-lfind){
char*p=strstrstr(缓冲区,查找);
如果(p){
移除_str(p+lfind,find,lfind);
//把所有东西移到左边
do{*p=*(p+lfind);}while(*(++p));
}
}
int main(){
文件*fp1,*fp2;
字符键[1000],a[1000];
//要求钥匙前面有空格
键[0]='';
printf(“\n输入要从文件中删除的单词:”;
scanf(“%s”和键[1]);
fp1=fopen(“a.txt”,“r”);
fp2=fopen(“b.txt”,“w”);
而(fgets(a、1000、fp1)){
移除_str(a,键,strlen(键));
FPUT(a,fp2);
}
fclose(fp1);
fclose(fp2);
printf(“\n\n”);
返回0;
}

另一个解决方案。它有上面提到的一些相同的问题,例如一个单词的边界与英语语法不匹配。此外,在某些情况下,它的复制效率也很低,超出了严格必要的数量

但是,我更喜欢这个版本,因为它抽象了单词删除任务,而不是与代码的其余部分内联。而且效果更好

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

void remove_str2(char* buffer, char* find, int lfind) {
  char* paste = strstr(buffer, find);
  if (!paste) { return; }
  char* start = paste + lfind;

  while (1) {
    char* end = strstr(start, find);
    if (!end) {
      end = start + strlen(start) + 1;
    }
    memmove(paste, start, end - start);

    paste += end - start;
    start = strstr(end, find);
    if (!start) { return; }
    start += lfind;
  }
}

void remove_str(char* buffer, char* find, int lfind) {
  char* p = strstr(buffer, find);
  if (p) {
    remove_str(p + lfind, find, lfind);
    // shift everything left
    do { *p = *(p + lfind); } while (*(++p));
  }
}

int main() {
  FILE *fp1, *fp2;
  char key[1000], a[1000];

  // require key to be preceeded by a space
  key[0] = ' ';

  printf("\nEnter the word to be deleted from file : ");
  scanf("%s", &key[1]);

  fp1 = fopen("a.txt","r");
  fp2 = fopen("b.txt","w");

  while (fgets(a, 1000, fp1)) {
    remove_str(a, key, strlen(key));
    fputs(a, fp2);
  }

  fclose(fp1);
  fclose(fp2);

  printf("\n\n");

  return 0;
}
#包括
#包括
void remove_str2(字符*缓冲区、字符*查找、整数lfind){
char*paste=strstrstr(缓冲区,查找);
如果(!粘贴){return;}
char*start=paste+lfind;
而(1){
char*end=strstrstr(开始,查找);
如果(!结束){
结束=开始+strlen(开始)+1;
}
memmove(粘贴、开始、结束-开始);
粘贴+=结束-开始;
开始=strstr(结束,查找);
如果(!start){return;}
sta