关于续写文件时文件指针的处理问题(70分)

  • 主题发起人 主题发起人 cdvoice415
  • 开始时间 开始时间
C

cdvoice415

Unregistered / Unconfirmed
GUEST, unregistred user!
想解决这样一个问题:
文件以”ab“方式打开,按按钮a则写入n个字符,比如第一次写入1,
第二次写入2,3,第三次为4,5,6。。。。则文件变为123456。。
现在想做一个按钮b,如果按一下b,则下一次再按按钮a则会在前一次
基础上续写,而不是在文件末尾续写。
比如这一次写入789,文件变为123456789,按一下按钮b,再按按钮a
写入234,则文件变为123456234,而不是在末尾续写,不是变成123456789234。
每一次按按钮b,就可以在前一次的基础上续写,就是覆盖掉最近一次的写入。
尝试过用feek来改变文件指针的位置,但好像总是在文件末尾续写,不能
实现预定功能。
请大侠们帮帮忙,用c或者c++语言实现一下。thx!!!
 
r+t
ab 是不能修改的.
不过可以在内存中构造,程序退出时再写成文件.
 
r+t是打开方式吗?
在内存中构造好像可以,不过我要存的不是123那么简单
是很多种结构
想起来好像很复杂

可能不能实现了55
 
下面这个例程实现的功能是:如果文件不存在,就建立文件,否则就打开文件以注的方式
使用,如果点击WriteBtn按钮写文件,数据会被追回,但如果点ReWriteBtn按钮写文件,
新数据会覆盖上一次写的的数据。但要注意,如果文件放关闭后重新打开,原来的光标位置
就会无效,所以如果每次点了ReWriteBtn写数据后就关闭文件又重新打开的话,其结果还
是追回模式而不是覆盖模式。
这只是一个简单的例子,你可以参照它完成更复杂的业务逻辑,关键就是自己灵活设置光标
了。
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <stdio.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
FILE *fp;
long CurPos=0;
const char sFileName[]="C://Test1.txt";
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WriteBtnClick(TObject *Sender)
{
int iNumber;
if (!fp){
MessageBox(Handle, "打开文件失败,不能写入", "Error", MB_ICONERROR);
return;
}
iNumber = atoi(Edit1->Text.c_str());
fwrite(&amp;iNumber, sizeof(iNumber), 1, fp);
if (fflush(fp)==0) //清空缓存,将数据写到硬盘上
MessageBox(Handle, "OK!", "Write", MB_ICONINFORMATION);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReWriteBtnClick(TObject *Sender)
{
int iNumber;
if (!fp){
MessageBox(Handle, "打开文件失败,不能写入", "Error", MB_ICONERROR);
return;
}
iNumber = atoi(Edit1->Text.c_str());
fseek(fp, CurPos, SEEK_SET);
fwrite(&amp;iNumber, sizeof(iNumber), 1, fp);
if (fflush(fp)==0)
MessageBox(Handle, "OK!", "Write", MB_ICONINFORMATION);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//不能用"wb+"打开文件,因为它会重写文件,也不能用"ab+"打开文件,
//因为每一次写都会变成追加模式
if ((fp = fopen(sFileName, "rb+"))==NULL){
//打不开文件,建立之
if ((fp = fopen(sFileName, "wb+"))==NULL)
MessageBox(Handle, "打开文件失败!", "Error", MB_ICONERROR);
}
//文件被关闭后,光标将无效,重新打开后关标将被放在文件尾
fseek(fp, 0, SEEK_END);
CurPos = ftell(fp);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if (fp)
fclose(fp);
}
//---------------------------------------------------------------------------
 
我对于这种问题是这样做的,利用TStringList存储文件的内容,最后一次写入文件。
我以前用Delphi是这么做的,现在用Java也是这样。
 
Sachow和fly-king大侠的邮箱可否告知?
另外,用tstringlist怎么做啊?
没有用过^_^谢谢
 
To fly-king:TStringList能处理二进制文件吗?请尝试之。
To cdvoice415:如果需要处理二进制文件,最好用标准的C/C++文件处理函数(如上例所示),或TFileStream
来处理。TFileStream的用法与前者有些近似。
 
re sachow :
我真的用字符串作过格式已知的文件的操作,现在正在做关于Java的编译文件(*.class)
的处理。
 
To fly-king:由于所有字符串对象的特点都是一且遇到ASCII码0时就判断字符串结束,所以
如果使用TStringList的话,只能处理文本文件,不能处理二制文件,这一点在C/C++或PASCAL
上都是一样的。由于贴主的需求是要写入二制文件(要不然干嘛用"ab"方式打开吧),所以
不能用TStringList处理。
请执行以下代码,它会先后两次往文件中写入0和"XXX",如果采用TStringList的LoadFromFile
来读取文件,结果将是什么也读不到。
FILE *fp;
int a=0;
char sBuf[5]="";
strcpy(sBuf, "XXX");
if ((fp = fopen("C://TestBin.txt", "ab+"))==NULL)
return;
fwrite(&amp;a, sizeof(a), 1, fp);
fwrite(sBuf, sizeof(sBuf), 1, fp);
fwrite(&amp;a, sizeof(a), 1, fp);
fwrite(sBuf, sizeof(sBuf), 1, fp);
fclose(fp);
 
后退
顶部