1

如何从文件中删除从 i 到 i 的字节。

示例:"today me and my roomates went to a party"; 如果 i = 3,我想删除第 3 个字节、第 6 个、第 9 个......等我尝试使用 lseek 和 fgets,但我不知道如何做整个事情。

我尝试了什么:

FILE* f = fopen(name_file,"r");
lseek(f,0,SEEK_SET);
while(fgets(lune,255,f) != NULL){
     lseek(f,i,SEEK_SET);
}

我没有做太多,因为我不知道该怎么做。也许你可以帮助我一些答案和提示。

4

3 回答 3

2

流版本可能是一个更好的解决方案。然后让用户使用重定向(如果需要,使用管道或流到终端。)。不过,写而不是putchar()当然很容易实现。

#include <stdio.h>

void usage(char *myname)
{
    fprintf(stderr, "Usage: %s <file>\n", myname);
}

int main(int argc, char *argv[])
{
    FILE *fh;
    char *fn;
    int c;
    int i;
    int m = 3;

    if (argc != 2) {
        usage(argv[0]);
        return 1;
    }
    fn = argv[1];

    if (!(fh = fopen(fn, "r"))) {
        perror(fn);
        return 2;
    }

    i = 0;
    while ((c = fgetc(fh)) != EOF)
        if ((++i % m))
            putchar(c);

    return 0;
}
于 2013-10-31T19:45:47.433 回答
2

如果删除是指从文件内容中物理删除字节(在文件中间),则不能这样做。您必须打开另一个文件并有选择地复制要保留的内容。所以方法如下:

  • open()用于读取的源文件(我假设低级 I/O,但 stdlibf*函数会类似地工作)
  • open()写入的目标文件
  • lseek()到正确的位置
  • read()要保留的部分
  • write()到目标文件
  • 重复最后 3 次操作,直到完成。

请注意,您调用lseek()FILE*正确的方法(检查您的编译器警告。您应该使用fseek()

另一种方法是mmap()读取文件并读取它的一部分,就好像它是一个数组一样。

最后,如果您的文件是一个简单的字符串,最简单的方法可能是在内存中读取它并将正确的部分复制到输出文件中。

于 2013-10-31T19:18:54.337 回答
0

最简单的是一次使用字符 I/O 调用。确保使用缓冲的 I/O 流(并使用 setvbuf())来避免非常糟糕的性能

FILE *f, *fout;
f = fopen(...);
foutp = fopen(...);

int i = 3, c, ii;

for (ii = 1; c = (getc(f)) != EOF; ++ii)
{
  if (ii % i == 0) 
  {
     putc(outf);
  }
}
fclose(f); 
fclose(fout);

当然,您可能需要在复制每三个字符后删除原始文件并将输出重命名为原始文件名。

添加

我还应该补充一点,这回答了你写的问题,但是如果处理文本文件,它会出现奇怪的行为,因为它会在部分时间省略行分隔符,但由于你指定了每 3 个字节,这就是它应该表现的行为。如果您想始终保留行分隔符,则一次使用一行 I/O 函数会更简单

于 2013-10-31T19:39:14.350 回答