请问C++高手,如何在一个文件里面来回写,又不删除以前的内容?

fblgzdq 2011-01-20 08:11:04

比如第一次写入
第一行: is good
第二行:
第三行: test only

第二次先回到文件开头

然后添加写入到之前的内容,以前内容不删除:
第一行: This is a very good one
第二行: hello
第三行: what is test -----

希望能够给出可以简单测试的代码?


还有我写文件都是先用
freopen("../out0.txt","w",stdout);
重定位
然后直接每回用
cout<<xyz
写入到文件

请问这样的话要用cout 如何实现上面的2次 输出到文件的效果呢?
   

多谢

...全文
875 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
jaylong35 2011-01-24
  • 打赏
  • 举报
回复
总的思路就是,读取保存,修改,写回
没有别的方法,只是看如果读取保存
jaylong35 2011-01-24
  • 打赏
  • 举报
回复


#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define LINE_LEN 1024 //每行的最大长度
#define MODIFY_TIMES 1 //修改的轮数
#define LINE_NUM 3 //总共有多少行,这个要和处理函数相对应

std::string ModifyStr0(const char * str)
{
//函数里的处理由你自己定义,根据需要设置,我这里直接返回了,以下同
std::string tstr = "This is a very good one";
return tstr;
}

std::string ModifyStr1(const char * str)
{
std::string tstr = "hello";
return tstr;
}

std::string ModifyStr2(const char * str)
{
std::string tstr = "what is test -----";
return tstr;
}

std::string ModifyStr3(const char * str)
{
std::string tstr = "This is a very good one,2";
return tstr;
}

std::string ModifyStr4(const char * str)
{
std::string tstr = "hello,2";
return tstr;
}

std::string ModifyStr5(const char * str)
{
std::string tstr = "what is test -----,2";
return tstr;
}

int main()
{
//定义函数指针数组,用来保存处理函数。其中,2为处理的次数,3为有多少行要处理
//这个是为了方便后面进行循环处理,如果不循环处理可以用独立的函数
std::string(*m_Func[2][3])(const char * str);

//初始化处理函数数组
m_Func[0][0] = ModifyStr0;
m_Func[0][1] = ModifyStr1;
m_Func[0][2] = ModifyStr2;
m_Func[1][0] = ModifyStr3;
m_Func[1][1] = ModifyStr4;
m_Func[1][2] = ModifyStr5;

int m = 0;
while(m < MODIFY_TIMES)
{
//外层循环为处理的轮数

//这个向量用来保存文件,一行一个push
vector<std::string> vFile;
vFile.clear();

//先读取文件,并调用函数进行处理,这个处理也可放到写入的时候
fstream fin;
fin.open("a.txt", ios::in);

char line[LINE_LEN];
memset(line,0,LINE_LEN);

fin.getline(line,LINE_LEN);

std::string strLine = m_Func[m][0](line);
vFile.push_back(strLine);
cout<<strLine<<endl;

int k = 1;
while(k < LINE_NUM && !fin.fail())
{
memset(line,0,LINE_LEN);

fin.getline(line,LINE_LEN);
//调用处理函数进行处理
std::string strLine = m_Func[m][k](line);
vFile.push_back(strLine);
cout<<strLine<<endl;

k++;
}
fin.close();

//把处理结果写入文件,覆盖原来的
fstream fout;
//以ios::trunc方式打开可以清空原来的数据,防止,如果是字符串变短,而有部分残留
fout.open("a.txt", ios::out|ios::trunc);
int i = 0;
while(i < vFile.size())
{
fout<<vFile[i]<<endl;
i++;
}
fout.close();
m++;
}
return 1;
}


这样子可不可以,随便写了一下
按你的要求,只要循环一轮就可以了,那么MODIFY_TIMES 1
fblgzdq 2011-01-23
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 yangglemu 的回复:]
来回写是可以的,但是要给文件定好格式,象保存链表的时候的搞法:
typedef struct _abc
{
char name[20];
char sex[10];
int age;
}abc;
文件中都是abc这样的结构一个挨着一个,如果结构中某个域为空,也要把它的位置留出来
这样你就可以来回写了
[/Quote]

Hi!
非常感谢。
请问可否贴下可以运行的代码演示下我前面的3次 输入,这样我测试下就可以明白你的意思了。 不知道为什么一定要有结构。 我算出具体的位置然后地动过去改就行了吧
  • 打赏
  • 举报
回复
来回写是可以的,但是要给文件定好格式,象保存链表的时候的搞法:
typedef struct _abc
{
char name[20];
char sex[10];
int age;
}abc;
文件中都是abc这样的结构一个挨着一个,如果结构中某个域为空,也要把它的位置留出来
这样你就可以来回写了
管哥的天下 2011-01-23
  • 打赏
  • 举报
回复
那分了,哈哈哈啊
iambic 2011-01-23
  • 打赏
  • 举报
回复
别给楼主乱出主意耽误他时间了,直接告诉他做不到死心算了。
  • 打赏
  • 举报
回复
用这个函数可以移动文件指针fseek(FILE*, long,int);
第三个INT参数是文件的位置,取值有三种:
SEEK_CUR
当前位置
SEEK_END
文件尾
SEEK_SET
文件头
第二个参数是相对第三个参数的偏移
移动到文件头可以这样: fseek(fp, 0, 0);
qq120848369 2011-01-23
  • 打赏
  • 举报
回复
不喂到嘴边你不满足,自己看C++ Primer。
  • 打赏
  • 举报
回复
增加新记录用"ab+"方式打开文件
可以用这种方法做一个自己的数据库,学C的人在学到文件这块都会这样玩玩的吧?
  • 打赏
  • 举报
回复
注意文件的的开方式
结构体定义
typedef struct
{
char name[20];
int age;
}People;//结构体大小24个char


//建立一个文件,写入了两个结构体P
int main()
{
FILE* fp=fopen("F:\\data.db", "wb+");
People p;
strcpy(p.name,"张三");
p.age=23;
fwrite(&p,1,24,fp);//24是结构大小
strcpy(p.name,"");
p.age=55;
fwrite(&p,1,24,fp);
fclose(fp);
return 0;


//读取:
int main()
{
FILE* fp=fopen("F:\\data.db", "r");//只读方式打开
int number = filelength(fp->_file)/24;//有多少个结构,或记录数
People p;
for(int i=0;i<number;i++)
{
fread(&p,1,24,fp);
printf("name:%20s\tage:%4d\n", p.name, p.age);
}
fclose(fp);
return 0;
}

//改写:
int main()
{
FILE* fp=fopen("F:\\data.db", "rb+");//读写方式打开
fseek(fp,24,0);//从文件头偏移24个字节,指向第二条记录
fwrite("李四",1,20,fp);
fclose(fp);
return 0;
}//改写后,可用上面的读取代码读取文件,看是否成功

上面代码在VC2008上跑过

fblgzdq 2011-01-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 taodm 的回复:]
因为文件是“流”,所以无法中间插入数据。
楼主要的恐怕是数据库,别自己试图在文件上搞了。
文件只有“重建整个文件”这唯一解。
[/Quote]

感谢帮我明确方向

请问第二次写的时候怎么把输出的位置移到整个文件的开始? 不是当前行的开始. 谢谢.
fblgzdq 2011-01-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qq120848369 的回复:]
你要自己在文件里写好你的测试用例,然后用代码运行.
[/Quote]

什么意思?

请问第二次写的时候怎么把输出的位置移到整个文件的开始? 不是当前行的开始. 谢谢.
fblgzdq 2011-01-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 luciferisnotsatan 的回复:]
先在内存里用个vector<string>做,然后一次性写到文件里
[/Quote]

hi!
因为要算很多东西,一边算一遍写,同时中间结果也会删除,然后又可能回头到文件开头写,
所以不能一次性写
或者说一次性写 消耗太大
jikeyuan1 2011-01-21
  • 打赏
  • 举报
回复
std::ios::app 把所有新数据写入到文件的尾部
std::ios::ate 把所有新数据写入到文件的尾部,如果程序移动了文件指针,就把数据写入到当前位置
qq120848369 2011-01-21
  • 打赏
  • 举报
回复
你要自己在文件里写好你的测试用例,然后用代码运行.
taodm 2011-01-21
  • 打赏
  • 举报
回复
因为文件是“流”,所以无法中间插入数据。
楼主要的恐怕是数据库,别自己试图在文件上搞了。
文件只有“重建整个文件”这唯一解。
noock 2011-01-21
  • 打赏
  • 举报
回复
下次再写的时候用fseek把指针移到开头
luciferisnotsatan 2011-01-21
  • 打赏
  • 举报
回复
先在内存里用个vector<string>做,然后一次性写到文件里
jaylong35 2011-01-21
  • 打赏
  • 举报
回复
第二次写的时候先把原来的句子读取出来,
然后按要求进行修改,再写入
这样子就是一边处理一边写了
fblgzdq 2011-01-21
  • 打赏
  • 举报
回复
std::cout<<" is good"<<endl; //我这里 is good 前面原来是输出了预留空格的
std::cout<<endl;
std::cout<<" test only"<<endl; // 这里我要是test 前预留了空格 论坛自动把空格删了


上面是完成了:
第一次写入
第一行: is good
第二行:
第三行: test only



现在我想要实现:
第二次先回到文件开头

然后添加写入到之前的内容,以前内容不删除:
第一行: This is a very good one //在原来 第一段的空格地方写入
第二行: hello 在原来的第二行的换行处写入
第三行: what is test ----- 在原来的test 前写入 并把 test 后的 only 等输出改为 ----


请问要是第三次 想在 某些单词间插入 句子要如何实现呢? 不删除原句,
比如现在变成

第一行: This is a really very good one //在原来 插入 really
第二行: heAAAllo //插入AAA
第三行: what is test -----


请问要是想实现输出一样的内容到文件和屏幕 又应该如何作了? 可同步也可不同步输出。

非常感谢

希望能够给出可以上述的测试的代码
加载更多回复(4)

64,654

社区成员

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

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