写了个精确复制文件程序,有问题


#1
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
	FILE *fa,*fb;
	if((fa=fopen("zao.mp3","rb"))==NULL)
	{
		printf("\ncan not open zao.mp3  !");
	    exit(1);
	}
	if((fb=fopen("yi.mp3","wb+"))==NULL)
	{
		printf("\ncan not create yi.mp3  !");
	    exit(1);
	}
	//char ch=fgetc(fa);
	while(feof(fa)!=1)
	{
		fputc(fgetc(fa),fb);
		//ch=fgetc(fa);
		}
	clearerr(fb);
	fclose(fa);
	fclose(fb);
	printf("cp zao.mp3 to yi.mp3 completely!\n");
	return 0;
}

yi.mp3成功生成,也可以播放。只是有问题:

wei@linux-vvbk:~/bin> od -c zao.mp3 | tail -n 2
10122220  \0
10122221
wei@linux-vvbk:~/bin> od -c yi.mp3 | tail -n 2
10122220  \0 377
10122222
wei@linux-vvbk:~/bin> 

多出来的 377 如何删掉?只是想通过本程序引出如何精确修改、删除字节问题。
如何精确删除或修改文件的某一(或几个)字节?


#2

又是一个不知道有程序框的人。


#3

fgetc 读到最后一个字符后,feof 返回 0。再次调用 fgetc,返回 EOF。这时候再 feof 结果才是非0。

你的程序多复制了一个 EOFEOF 的八进制就是 377

参考链接🔗:


#4

od -c zao.mp3 | grep 377
发现zao.mp3有很多377呀,不能
while ((c = fgetc(fa)) != EOF) { // standard C I/O file reading loop
fputc(c,fb);
}
否则就复制不完。改成:
while(feof(fa)==0)
fputc(fgetc(fa),fb);
还是多了一个377。
很多mp3文件中间都有377(EOF),这是为何?
先不谈程序的细节。如何精确删掉或修改二进制文件中字节?比如把zao.mp3中间的377改成别的字符?


#5

发现zao.mp3有很多377呀,不能
while ((c = fgetc(fa)) != EOF) { // standard C I/O file reading loop
fputc(c,fb);
}
否则就复制不完

这里 c 应该是 int, 而不是 char。否则无法区分 EOF 和文件中的0xff。


#6

改为:
int c;
while ((c = fgetc(fa)) != EOF) { // standard C I/O file reading loop
fputc(c,fb);
}
成功了,精确复制,最后再无多余的377。那么如何把文件中间的任意字符删除和修改?fputc或putc只会把字符加到最后。


#7

你也许需要一发pwrite


#8

为啥非要用fgetc/fputc,你之前的错误是出在fopen的参数用了“w”,fread和fwrite是没有错的。因为fopen
的时候,第二个参数是“w”,所以当前目录那个*.mp4文件自动被你清除了。之后你再写入新东西,当然只有32字节,不是fwrite把你的文件截断了,而是fopen因为你错误的调用方式把文件直接覆盖了!


#9

这恰好是《C 程序设计语言》第一章的习题,自己去找一本读读看。