如果只想修改文件的一两个字节,那么利用标准IO函数可以吗?

六道佩恩 2018-10-01 02:48:43
如果只想修改文件的一两个字节,那么利用标准IO函数可以吗?可以的话请问怎么做?我用a+也不能用fseek移动,如果不行,是不是说已写的文件不能改动,要改动只能新建文件?如果我想修改文件且名字不变,除了拷贝+删除原文件+改名这种方式,还有其他方法吗(感觉这种方法很low啊)?
...全文
675 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
wodeyouxian 2018-10-22
  • 打赏
  • 举报
回复
引用 28 楼 zhao4zhong1 的回复:
[quote=引用 27 楼 wodeyouxian 的回复:] C语言自已的库函数貌似是做不到对文件直接修改,最容易实现的方法还是先打开读到内存里,修改好后,再次打开文件,重新写入
扯[/quote] ============= 我试了好几次,用a+的方式打开文件时,可以在文件最后面增加内容,但这不符合楼主的要求;用r+和w+打开文件时,文件的长度直接变为0了,不知道你们有什么方法可以直接修改C的文件?能贴上可用的代码吗?
六道佩恩 2018-10-22
  • 打赏
  • 举报
回复
引用 21 楼 boxmanstan 的回复:
[quote=引用 19 楼 weixin_39158150 的回复:]
[quote=引用 17 楼 boxmanstan 的回复:]
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗


即便是r+,只要一经写入,就会立刻清空为空文件,大哥你都不实际操作看看的吗?[/quote]


VS2013测试OK[/quote]
我去,还真的可行,之前这个方案我测试过的,明明不行的来着,感谢老哥!
六道佩恩 2018-10-22
  • 打赏
  • 举报
回复
引用 22 楼 zhouqunhai 的回复:
读入,判断修改,重新写入

请问是指文件全部读入吗?
赵4老师 2018-10-20
  • 打赏
  • 举报
回复
引用 27 楼 wodeyouxian 的回复:
C语言自已的库函数貌似是做不到对文件直接修改,最容易实现的方法还是先打开读到内存里,修改好后,再次打开文件,重新写入
wodeyouxian 2018-10-19
  • 打赏
  • 举报
回复
C语言自已的库函数貌似是做不到对文件直接修改,最容易实现的方法还是先打开读到内存里,修改好后,再次打开文件,重新写入
杀意已决 2018-10-16
  • 打赏
  • 举报
回复
引用 23 楼 zhao4zhong1 的回复:
[quote=引用 17 楼 boxmanstan 的回复:]
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗

文件大小大于2GB时,fseek就不好用了。[/quote]

理解你的意思,offset是long型。
这个人一直在强调fwrite写入清空这个事,你给解释一下呗
赵4老师 2018-10-16
  • 打赏
  • 举报
回复
引用 17 楼 boxmanstan 的回复:
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗

文件大小大于2GB时,fseek就不好用了。
zhouqunhai 2018-10-16
  • 打赏
  • 举报
回复
读入,判断修改,重新写入
杀意已决 2018-10-16
  • 打赏
  • 举报
回复
引用 19 楼 weixin_39158150 的回复:
[quote=引用 17 楼 boxmanstan 的回复:]
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗


即便是r+,只要一经写入,就会立刻清空为空文件,大哥你都不实际操作看看的吗?[/quote]


VS2013测试OK
赵4老师 2018-10-16
  • 打赏
  • 举报
回复
When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.
赵4老师 2018-10-16
  • 打赏
  • 举报
回复
fwrite之前fopen时参数mode带a或w,清空很正常;
fwrite之前fopen时参数mode不带a或w而是r+b或rb+,就不会清空。
  • 打赏
  • 举报
回复
这段代码VS2008可以。

#include <stdio.h>

int main()
{
	FILE *pflIO = NULL;
	FILE *pflOut = NULL;

	pflOut = fopen("test.bin", "wb");
	if (NULL ==pflOut)
	{
		printf("创建文件失败");
		return -1;
	}
	else
	{
		for (char ch= 0; ch<100; ch++)
		{
			fwrite(&ch, 1, 1, pflOut);
		}
		fclose(pflOut);
	}

	pflIO = fopen("test.bin", "rb+");
	if (NULL == pflIO)
	{
		printf("打开要修改的文件错误");
	}
	else
	{
		fseek(pflIO, 10, SEEK_SET);
		char ch = 0;
		fwrite(&ch, 1, 1, pflIO);
		fclose(pflIO);
	}

	return 0;
}
六道佩恩 2018-10-15
  • 打赏
  • 举报
回复
引用 17 楼 boxmanstan 的回复:
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗


即便是r+,只要一经写入,就会立刻清空为空文件,大哥你都不实际操作看看的吗?
anguoguo 2018-10-13
  • 打赏
  • 举报
回复
引用 13 楼 weixin_39158150 的回复:
[quote=引用 3 楼 adlay 的回复:]
用内存映射, Windows CreateFileMapping, Linux mmap

这个在windows上可行吗?[/quote]
Windows上可以使用内存映射文件
AlbertS 2018-10-10
  • 打赏
  • 举报
回复
内容读出来,修改后再写回去
杀意已决 2018-10-10
  • 打赏
  • 举报
回复
你们在争什么?

1. fopen r+
2. fseek到你要修改的位置
3. fwrite写入你要修改的内容,设置要修改的大小,只会修改你写入大小的内容,后面的不变

不就这么个事吗
hongwenjun 2018-10-08
  • 打赏
  • 举报
回复
这个源码 查看文件头 3字节。如果已经有就不添加 如果没有文件头BOM, 就分配文件大小+3的内存,读取整个文件,修改后再写回去
赵4老师 2018-10-08
  • 打赏
  • 举报
回复
仅供参考:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
FILE *f;
char ln[64+1];//Because sscanf(argv[66],"%hx",&ln[66-3]); modify ln[63] and ln[64] !
int i;
__int64 hexoffset64;
void main(int argc,char *argv[]) {
if (argc<=3) {
cprintf("Locate & Replace, designed by zhao4zhong1@163.com\n\r");
HELP:
cprintf("Usage: LR filename.ext hexoffset64 byte1 byte2 byte3 ...");
return;
}
if (argc>64+3) {
cprintf("Up to 64 bytes\a");
return;
}
if ((f=fopen(argv[1],"r+b"))==NULL) {
cprintf("Can not open %s\a",argv[1]);
return;
}
if (1!=sscanf(argv[2],"%I64x",&hexoffset64)) {fclose(f);goto HELP;}
if (hexoffset64>=_filelengthi64(_fileno(f))) {
cprintf("hexoffset64==%016I64x >= %016I64x==_filelengthi64 of file %s\a",hexoffset64,_filelengthi64(_fileno(f)),argv[1]);
fclose(f);
return;
}
for (i=3;i<argc;i++) {
if (1!=sscanf(argv[i],"%hx",&ln[i-3])) {fclose(f);goto HELP;}
}
if (hexoffset64!=_lseeki64(_fileno(f),hexoffset64,SEEK_SET)) {
cprintf("_lseeki64 to %I64x fail\a",hexoffset64);
fclose(f);
return;
}
if ((int)fwrite(ln,1,argc-3,f)!=argc-3) {
cprintf("fwrite %d bytes fail\a",argc-3);
fclose(f);
return;
}
fclose(f);
}
六道佩恩 2018-10-08
  • 打赏
  • 举报
回复
引用 3 楼 adlay 的回复:
用内存映射, Windows CreateFileMapping, Linux mmap

这个在windows上可行吗?
六道佩恩 2018-10-08
  • 打赏
  • 举报
回复
引用 11 楼 hongwenjun 的回复:
FILE* f = fopen(it->wholePath.c_str(), "rb");
if (!f)
{
cerr << "Error: Cannot open" << it->wholePath << endl;
continue;
}
unsigned char buf[10];
fread(buf, 1, 3, f);

// Get file size:
fseek(f, 0, SEEK_END);
const long N = ftell(f);
fclose(f);

if (buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
{
cout << "Skipping (already has BOM): " << it->wholePath << endl;
continue;
}

// Add BOM: =======================================
// Read the whole file:
unsigned char* fil_buf = new unsigned char[N + 3];
fil_buf[0] = 0xEF;
fil_buf[1] = 0xBB;
fil_buf[2] = 0xBF;

f = fopen(it->wholePath.c_str(), "rb");
fread(fil_buf + 3, 1, N, f);
fclose(f);

// Write new version:
f = fopen(it->wholePath.c_str(), "wb");
fwrite(fil_buf, 1, N + 3, f);
fclose(f);

delete[] fil_buf;

cout << "Added BOM: " << it->wholePath << endl;


老哥,你这个程序是把文件内容都读入内存然后再重新写入这个文件是吗?
加载更多回复(11)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧