Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中删除没有临时文件的行_C_File Handling - Fatal编程技术网

在C中删除没有临时文件的行

在C中删除没有临时文件的行,c,file-handling,C,File Handling,我试图通过用下一行替换该行来删除给定行,但它不会改变任何东西 int i=0,n,j,p; char s[80]; FILE *fp; scanf("%d",&n); fp = fopen("test.txt","r+"); while(fgets(s,sizeof(s),fp)!=NULL){ i++; if(i==n) break; j = ftell(fp); } while(fgets(s,60,fp)!=NULL){ p = f

我试图通过用下一行替换该行来删除给定行,但它不会改变任何东西

int i=0,n,j,p;
char s[80];
FILE *fp;
scanf("%d",&n);
fp = fopen("test.txt","r+");
while(fgets(s,sizeof(s),fp)!=NULL){
    i++;
    if(i==n)
        break;
    j = ftell(fp);
}

while(fgets(s,60,fp)!=NULL){
    p = ftell(fp);
    fseek(fp,0,j);
    fprintf(fp,"%s",s);
    j = p;
    fseek(fp,0,SEEK_CUR);
}
fclose(fp);

fseek(fp,0,j)中的参数错误。第三个参数需要是
SEEK_xxx
常量之一,因此它应该是
fseek(fp,j,SEEK_SET)
您在
fseek(fp,0,j)中有错误的参数。第三个参数需要是
SEEK_xxx
常量之一,因此它应该是
fseek(fp,j,SEEK_SET)

我认为删除第一行不起作用。当你设置
j
时,你已经读过了。我认为你的整个算法都搞糟了。如果一行比前一行短,则只覆盖一行的一部分,然后再读取替换行的其余部分。如果这行较长,你会写得太远。我还没有弄清楚如何修复它,但是如果在第二个循环中读取固定大小的字符串,而不是按行读取,则会更容易。解决@Barmar所指问题的方法可能是逐字符移动,而不是逐行移动。效率很低。一种更简单的方法可能是使用内存映射文件,只需将文件的剩余部分
memmove()
移到要删除的行的开头。@Clifford逐字符只是固定大小字符串的一种限制情况。内存映射是特定于操作系统的。但你也可以将整个文件读入内存,寻找要删除的行,然后在该行之后写入内存缓冲区的一部分。在所有这些方法中,你需要在最后一行之后截断文件,以删除结尾的多余行。我认为这不适用于删除第一行。当你设置
j
时,你已经读过了。我认为你的整个算法都搞糟了。如果一行比前一行短,则只覆盖一行的一部分,然后再读取替换行的其余部分。如果这行较长,你会写得太远。我还没有弄清楚如何修复它,但是如果在第二个循环中读取固定大小的字符串,而不是按行读取,则会更容易。解决@Barmar所指问题的方法可能是逐字符移动,而不是逐行移动。效率很低。一种更简单的方法可能是使用内存映射文件,只需将文件的剩余部分
memmove()
移到要删除的行的开头。@Clifford逐字符只是固定大小字符串的一种限制情况。内存映射是特定于操作系统的。但是你也可以将整个文件读入内存,寻找要删除的行,然后在该行之后写入内存缓冲区的一部分。在所有这些方法中,你需要在最后一行之后截断文件,以删除末尾的多余行。