C++ 流的使用 Part I - file iostream

继承图


pic_1


一个简单的流处理的例子。


基本的函数:
in.get(buffer, SIZE)   读取文件中的一行到buffer中,如果这一行字符的长度大于buffer的size, 他会先读满buffer->处理,然后继续读取,一直读到'/n' 字符。

程序中使用 in.get(); 来读取'/n',并且把'/n'跳过去,如果不使用它的话,在while (in.get(buffer, SIZE))中下次还会读取 '/n'while 循环跳出,只读了文件的第一行。


Sample 1

#include <fstream>
#include <iostream>


using namespace std;


void main()
{
	const int SIZE = 100;
	char buffer[SIZE];
	int i = 0;


	{
		ifstream in("log.txt");
		ofstream out("logout1.txt");


		// if the string length is larger then the buffer SIZE
		// it will read the max size of buffer and read again until meet '/n'
		while (in.get(buffer, SIZE))
		{
			in.get();       // in.get(buffer, SIZE) meet '/n' will return, so here must read a char and throw the character '/n' then 
			                // while loop can continue or the program will just read the first line.
			cout << buffer << endl;
			out << i++ << " : " <<buffer << endl;
		}
	}  // here in and out stream will be closed and released


	{
		ifstream in("logout1.txt");
		while (in.get(buffer, SIZE))
		{
			char* pchar = buffer;
			while (*pchar != ':')
				pchar++;


			*pchar = '-';


			in.get();
			cout << buffer << endl;
			out << buffer << endl;
		}
	}
	cin >> i;
}



打开模式

ios::in          打开输入文件,以这种方式用于ostream打开,使得现存文件不被截断,相当于把文件从头开始重新写入,但保留原来文件中没有被重写的部分。


ios::out         打开输出文件,以这种方式用于ostream 打开一个仅用于追加的文件,且未使用ios::in, ios::app, ios::ate时等同于使用ios::trunc。相当于如果文件存在,把文件中原有的内容清空,并且重新写入新的内容。


ios::app         打开一个仅用于追加的文件。


ios::ate         打开一个已存在的文件(输入或输出),并把指针指向文件末尾。


ios::trunc       如果文件存在则截断旧文件


ios::binary      以二进制方式打开文件


这些打开方式当然可以结合使用: out.open("Hello.txt", ios::in|ios::out|ios::binary)



测试用 log.txt 文件

a
bb
ccc
dddd
eeeee
ffffff
ggggggg
hhhhhhhh


ios::in 的一个例子

在这个例子中 logout2.txt 被写了两次,可以从测试结果中发现这种打开模式的作用。

#include <fstream>
#include <iostream>

using namespace std;

void main()
{
	const int SIZE = 100;
	char buffer[SIZE];
	int i = 0;


	{
		ifstream in("log.txt");
		ofstream out("logout1.txt");
		ofstream out2("logout2.txt");


		// if the string length is larger then the buffer SIZE
		// it will read the max size of buffer and read again until meet '/n'
		while (in.get(buffer, SIZE))
		{
			in.get();       // in.get(buffer, SIZE) meet '/n' will return, so here must read a char and throw the character '/n' then 
			                // while loop can continue or the program will just read the first line.
			cout << buffer << endl;
			out << i++ << " : " <<buffer << endl;
			out2 << i++ << " : " <<buffer << endl;
			out2 << i++ << " : " <<buffer << endl;
		}
	}  // here in and out stream will be closed and released


	{
		ifstream in("logout1.txt");
		ofstream out("logout2.txt", ios::in);


		while (in.get(buffer, SIZE))
		{
			char* pchar = buffer;
			while (*pchar != ':')
				pchar++;


			*pchar = '-';


			in.get();
			cout << buffer << endl;
			out << buffer << endl;
		}
	}
	cin >> i;
}



ios::in 测试结果:


logout1.txt 的测试结果
0 : a
3 : bb
6 : ccc
9 : dddd
12 : eeeee
15 : ffffff
18 : ggggggg
21 : hhhhhhhh

logout2.txt第一次写入:
1 : a
2 : a
4 : bb
5 : bb
7 : ccc
8 : ccc
10 : dddd
11 : dddd
13 : eeeee
14 : eeeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh


logout2.txt第二次写入:红色部分其实为上次写入的部分。
0 - a
3 - bb
6 - ccc
9 - dddd
12 - eeeee
15 - ffffff
18 - ggggggg
21 - hhhhhhhh
eeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh



使用 ios::out / ios::trunc 的测试结果: 

可以看到logout2.txt 中原有的内容被全部清空,并重新写入。



logout1.txt 的测试结果
0 : a
3 : bb
6 : ccc
9 : dddd
12 : eeeee
15 : ffffff
18 : ggggggg
21 : hhhhhhhh


logout2.txt第一次写入:
1 : a
2 : a
4 : bb
5 : bb
7 : ccc
8 : ccc
10 : dddd
11 : dddd
13 : eeeee
14 : eeeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh


logout2.txt第二次写入:
0 - a
3 - bb
6 - ccc
9 - dddd
12 - eeeee
15 - ffffff
18 - ggggggg
21 - hhhhhhhh




使用 ios::app 只是在文件末尾追加新的内容

logout1.txt 的测试结果

0 : a
3 : bb
6 : ccc
9 : dddd
12 : eeeee
15 : ffffff
18 : ggggggg
21 : hhhhhhhh

logout2.txt第一次写入:
1 : a
2 : a
4 : bb
5 : bb
7 : ccc
8 : ccc
10 : dddd
11 : dddd
13 : eeeee
14 : eeeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh


logout2.txt第二次写入:

1 : a
2 : a
4 : bb
5 : bb
7 : ccc
8 : ccc
10 : dddd
11 : dddd
13 : eeeee
14 : eeeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh
0 - a
3 - bb
6 - ccc
9 - dddd
12 - eeeee
15 - ffffff
18 - ggggggg
21 - hhhhhhhh





ios::ate 的测试: 

用于instream 比较明显,当第二次使用ate打开文件 logout1.txt时,指针指向了文件的末尾,所以logout2.txt没有任何的输入。在使用outstream时它也会把文件清空,并重新写入。


logout1.txt 的测试结果
0 : a
3 : bb
6 : ccc
9 : dddd
12 : eeeee
15 : ffffff
18 : ggggggg
21 : hhhhhhhh


logout2.txt第一次写入:
1 : a
2 : a
4 : bb
5 : bb
7 : ccc
8 : ccc
10 : dddd
11 : dddd
13 : eeeee
14 : eeeee
16 : ffffff
17 : ffffff
19 : ggggggg
20 : ggggggg
22 : hhhhhhhh
23 : hhhhhhhh


logout2.txt第二次测试结果文件为空。





文件流中的定位



输入输出流中定位用到的函数主要有4个 : tellp()  tellg()  seekp()  seekg()


对于ostream调用 tellp() 获得写指针的位置, seekp() 设置写指针的位置。


对于istream调用 tellg() 获得读指针的位置, seekg() 设置读指针的位置。



代码示例:

#include <fstream>
#include <iostream>

using namespace std;

void main()
{
	const int SIZE = 100;
	char buffer[SIZE];

	int i = 0;

	ifstream in("log.txt");
	ofstream out("logout1.txt");

	in.seekg(0, ios::end);

	streampos sp = in.tellg();

	cout << "file size = " << sp << endl;

	in.seekg(-sp/3, ios::end);

	streampos sp2 = in.tellg();
	cout << "from file to point sp2: " << sp2 << endl;

	cout << "read file from the beginning" << endl;
	cout << "============================================" << endl;
	in.seekg(0, ios::beg);
	cout << in.rdbuf() << endl << endl;

	// copy to output file
	in.seekg(0, ios::beg);
	out << in.rdbuf() << endl << endl;


	cout << "read file from a set position" << endl;
	cout << "============================================" << endl;
	in.seekg(sp2);
	cout << in.rdbuf() << endl << endl;


	streampos outsp1 = out.tellp();
	cout << "in output stream where is the position : " << outsp1 << endl;
	out.seekp(-outsp1/2, ios::end);

	in.seekg(sp2);
	out << in.rdbuf() << endl << endl;


	cin>> i;

}



测试结果:

pic_console




output.txt 第一次复制 log.txt 文件的结果

a
bb
ccc
dddd
eeeee
ffffff
ggggggg
hhhhhhhh



第二次插入式写入的结果

a
bb
ccc
dddd
eeeee
ff gggggg
hhhhhhhh



hhh


可以看出,
ggggggg
hhhhhhhh


被插入在指定,并且刷新了原来的文件。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值