打开文件,又要添加,又要改写,怎么办?

yaoyansi 2010-08-12 01:38:33

#include <cassert>
#include <fstream>
#include <iostream>
using namespace std;

#define _CLogDebug(_log) { std::cout << _log<< std::endl; }

//
void test_File_append()// ftell, fseek,
{
FILE *mc = NULL;
errno_t err = fopen_s(&mc, "F:/c++/tst/binary_file_append/binary_file_append/testfile_c.mc", "wb");
if (err != 0){
_CLogDebug("Error opening file");
return ;
}
// append ABC
fseek(mc, 0, SEEK_END);
fwrite("ABC", 3, 1, mc);

// append W
long posBlockSize=ftell (mc);
fwrite("W", 1, 1, mc);
_CLogDebug("posBlockSize="<<posBlockSize);

// append XYZ
fwrite("XYZ", 3, 1, mc);
long posBlockEnd=ftell (mc);
_CLogDebug("posBlockEnd="<<posBlockEnd);

// modify W
fseek(mc, posBlockSize, SEEK_SET);
_CLogDebug("modify W pos="<<ftell (mc));
fwrite("M", 1, 1, mc);

fseek(mc, posBlockEnd, SEEK_SET);
assert(ftell(mc)==posBlockEnd);

//期望结果:ABCMXYZ 实际结果:ABCWXYZM

fclose(mc);
}
//
void test_File_append2()// fgetpos, fsetpos
{
FILE *mc = NULL;
errno_t err = fopen_s(&mc, "F:/c++/tst/binary_file_append/binary_file_append/testfile_c2.mc", "ab");
if (err != 0){
_CLogDebug("Error opening file");
return ;
}
// append ABC
fseek(mc, 0, SEEK_END);
fwrite("ABC", 3, 1, mc);

// append W
fpos_t posBlockSize;
fgetpos(mc, &posBlockSize);
fwrite("W", 1, 1, mc);
_CLogDebug("posBlockSize="<<posBlockSize);

// append XYZ
fwrite("XYZ", 3, 1, mc);
fpos_t posBlockEnd;
fgetpos(mc, &posBlockEnd);
_CLogDebug("posBlockEnd="<<posBlockEnd);

// modify W
fsetpos(mc, &posBlockSize);
_CLogDebug("modify W pos="<<ftell (mc));
fwrite("M", 1, 1, mc);

fsetpos(mc, &posBlockEnd);
assert(ftell(mc)==posBlockEnd);

//期望结果:ABCMXYZ,实际结果:ABCWXYZM

fclose(mc);
}
int main()
{
//test_File_append();
test_File_append2();
return 1;
}



期望结果:ABCMXYZ,实际结果:ABCWXYZM

我该怎么办呢?
...全文
507 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
virgil0236 2010-08-13
  • 打赏
  • 举报
回复
自己想办法弄就行啦,二次追加的时候把内容取出来,暂存一下,再同要加入的数据一起再写进去
kaxnet 2010-08-13
  • 打赏
  • 举报
回复
就是update嘛, 用r+打开

FILE* f = fopen("filename", r+);


可以用fseek代替append

FILE* f = fopen("filename", r+);
fseek(f, 0, SEEK_END);
fwrite("something", sizeof(char), cnt, f);
fclose(f);
f = 0;


不过使用时要注意r+是可以读取的, a则不可以
其他打开方式可以去参考
http://www.cplusplus.com/reference/clibrary/cstdio/fopen/


longcpp 2010-08-13
  • 打赏
  • 举报
回复
//马上要睡着了,突然想起来了,可以实现的
//第二次打开文件的时候用如下语句:
//fstream f2( "out.txt", ios_base::in | ios_base::out | ios_base::binary );
//打开后,将文件指针定位到文件末尾f2.seekp( 0,ios_base::end );
//然后写入内容,因为要修改的W,位置距离文件尾部4*sizeof(char)
//将文件指针定位到相应地址:
//f2.seekp( -4*static_cast<streampos>(sizeof(char)),ios_base::end );
//改写内容f2.write( &ch1, sizeof(char) );
///////////////////////////程序代码如下/////////////////////////////

#include <iostream>
#include <fstream>
#include <cstdlib>

int main()
{
using namespace std;
ofstream file("out.txt", ios_base::out | ios_base::binary );
if( !file.is_open() )
{
cerr << "cannot open file" << endl;
exit( EXIT_FAILURE );
}
cout << "enter three chars: ";
char ch;
while( cin >> ch && !cin.eof() )
file.write( const_cast<const char*>(&ch), sizeof (char) );
cin.clear();
file.close();

fstream f2( "out.txt", ios_base::in | ios_base::out | ios_base::binary );
if( !f2.is_open() )
{
cerr << "cannot open f2" << endl;
exit( EXIT_FAILURE );
}
f2.seekp( 0,ios_base::end );
cout << "enter W and another three chars: ";
while( cin >> ch && !cin.eof() )
f2.write( &ch, sizeof (char) );

//将倒数第四个字符改为'M'
const char ch1 = 'M';
f2.seekp( -4*static_cast<streampos>(sizeof(char)),ios_base::end );
f2.write( &ch1, sizeof(char) );

//输出文件内容
if( !f2.is_open() )
{
cerr << "cannot open file" << endl;
exit( EXIT_FAILURE );
}
cout << "content in the out.txt file: " << endl;
f2.seekg( 0 );
while( f2.read( &ch, sizeof (char) ) )
cout << ch << " " ;
f2.close();
cout << endl;

return 0;
}
//////////////////////程序运行如下/////////////////////////////
//enter three chars: A B C
//^Z
//enter W and another three chars: W X Y Z
//^Z
//content in the out.txt file:
//A B C M X Y Z
//////////////////////////////////////////////////////////////
一起学习哈…… 呵呵
希望对你有所帮助
lovestefanie 2010-08-13
  • 打赏
  • 举报
回复
自己计算文件的偏移量
longcpp 2010-08-13
  • 打赏
  • 举报
回复
添加的话需要指定ios_base::app模式,可是这样无法改写。
可不可以再添加一次文件的关闭与打开操作,这样就可以实现了。
不过貌似这样跟楼主的需求不太相符,多了一次文件打开关闭操作。
ayw215 2010-08-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 adventurelw 的回复:]

没有办法直接改写文件吧,只能读取文件数据,修改数据,重新保存(应该是整个文件重新写一遍)。
添加好像是可以任意位置添加。
[/Quote]

不过文件指针的移位需要自己来做
adventurelw 2010-08-12
  • 打赏
  • 举报
回复
没有办法直接改写文件吧,只能读取文件数据,修改数据,重新保存(应该是整个文件重新写一遍)。
添加好像是可以任意位置添加。
yaoyansi 2010-08-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qinken547 的回复:]

6楼的那个例子你没看懂啊
用w的方式打开,最后输出结果是This is a sample怎么用w模式打开就清空了
[/Quote]

那是因为它本来打开的就是个空文件啊
qinken547 2010-08-12
  • 打赏
  • 举报
回复
6楼的那个例子你没看懂啊
用w的方式打开,最后输出结果是This is a sample怎么用w模式打开就清空了
这个例子是告诉你用fseek函数....
添加的话当然用a...
yaoyansi 2010-08-12
  • 打赏
  • 举报
回复
楼上,不行的

我的需求里:
重新打开文件,在末尾添加W,
写入(添加)XYZ,
改写W的值为M
关闭文件。

你用w模式打开,原先的文件就被清空了。
qinken547 2010-08-12
  • 打赏
  • 举报
回复
/* fseek example */
#include <stdio.h>

int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "w" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}

This is a sample
yaoyansi 2010-08-12
  • 打赏
  • 举报
回复
求助,在线等啊
yaoyansi 2010-08-12
  • 打赏
  • 举报
回复
不行吧,

在重新打开这个文件的时候,你用什么模式打开?
用"wb"会清空原有的文件,
用"ab"无法改写

怎么办?
jackyjkchen 2010-08-12
  • 打赏
  • 举报
回复
利用文件偏移,善用seek
yaoyansi 2010-08-12
  • 打赏
  • 举报
回复
我的需求是:

打开文件
写入ABC,
关闭文件

重新打开文件,在末尾添加W,
写入(添加)XYZ,
改写W的值为M
关闭文件。

我该如何实现呢?
qinken547 2010-08-12
  • 打赏
  • 举报
回复
你用的是追加的方式写入的....
要改写只能写进去覆盖原来的内容....

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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