2013-10-31 47 views
1

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

例如:"today me and my roomates went to a party"; 若i = 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); 
} 

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

+0

是否要修改文件本身?如果是这样,您将希望以超过READ模式打开它。先尝试'r +'来真正能够更新文件。 –

+0

@bwtrent我想打开该文件,将修改后的行复制到另一个文件中,删除原始文件并用原始文件的名称重命名新文件。 – MathMe

+0

查看类似(但不重复):http://stackoverflow.com/questions/14905126/using-c-to-replace-the-first-half-of-a-file-with-the-second-and-截断 – hyde

回答

1

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

  • open()读取源文件(我认为低级别的I/O,但STDLIB f*功能将类似的工作)
  • open()目标文件写
  • lseek()到正确的位置
  • read()的部分,以保持
  • write()到目标文件
  • 重复最后3个操作直到完成。

请注意,您在FILE*呼吁lseek()这是正确的方式(请检查您的编译器警告。您应该使用fseek()

另一种方式是mmap()文件和读取的部分就好像它是一个数组。

最后,如果你的文件是一个简单的字符串,最简单的方法可能是在内存中读取它,正确的文件拷贝到输出文件。

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); 

当然,你可能需要删除原始文件和输出后重命名回原来的文件名你已经复制了每第三个字符。

ADDED

我还要补充一点,这个答案是写你的问题,但它有奇怪的行为,如果处理文本文件,因为它会忽略当时的行分隔符的一部分,但因为你指定的每3字节,这是谁应该表现的。如果您想始终保留行分隔符,则一次使用该行更简单I/O功能

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; 
}