文件流、指针偏移、流状态位 与圣经文件练习

一个人想着一个人 提交于 2020-01-17 19:23:53

文件流、指针偏移、流状态位与圣经文件练习


一.文件流

在文件流中, 定义的类型有:

fstream 既可以是输入流也可以是输出流
ifstream 输入流
ofstream 输出流

在对文件进行操作前,需要以open的形式打开,第一个参数是filename, 第二个参数是mode

mode 含义
ios::in 读方式
ios::out 写方式
ios::app 一般结合写方式,在文末尾进行追加
ios::ate 一般结合读方式,指针跳到末尾
ios::trunc 以截断方式打开,也就是将文件长度变为0

注意:
1.当定义 ifstream 时, 默认以 ios::in 打开;
2.当定义 ofstream 时, 默认以 ios::out|ios::trunc 打开;

  • 向文本中写数据
//尝试向文本中写数据
void Write() {
	
	ofstream fout;
	fout.open("data.txt", ios::out|ios::trunc);//即使不写,ofstream生成的默认mode也是ios::|ios::trunc
	fout << "name:wk" << " age:21" << endl;

	ofstream fout2;
	fout2.open("data.txt", ios::app);
	fout2 << "name:wwx" << " age:23" << endl;

	fout.close();
	fout2.close();
}

  • 文本中读取数据

文本中读取数据方式总结:
1.按行读取:
使用.getline()函数,遇到’\n’自动转换为’\0’, 且读取到EOF时终止返回NULL

//文本中读数据 一行一行的读
void ReadByLine() {
	ifstream fin;
	fin.open("data.txt", ios::in);//即使不写,默认的mode也是ios::in
	char buffer[1000];
	while (fin.getline(buffer, sizeof(buffer))) {//文档中有EOF结束符,当getline读到EOF(结束符)时返回NULL
		cout << buffer << endl;
	}

	fin.close();
}

2.按单词读取:
使用>>流读取,流读取的过程中遇到空白时会结束,读取到EOF时返回NULL

//文本中读数据 一个单词一个单词的读
void ReadByWord() {
	ifstream fin;
	fin.open("data.txt", ios::in);
	char word[100];
	while (fin >> word) {//注意在使用流操作的过程中流会自动忽略空白部分
		cout << word << endl;
	}

	fin.close();
}

3.按字符读取:
使用.get()函数读取,get函数除了EOF之外的字符都会进行读取。

//文本中读数据 一个字符一个字符的读
void ReadByChar() {
	ifstream fin;
	fin.open("data.txt", ios::in);
	char ch;
	while (fin.get(ch)) {//get函数会将所有字符(除了终止符EOF),全部读取
		cout << ch;
	}

	fin.close();
}

二.流状态位

流状态位 含义
goodbit 流状态正常时为1
failbit 流状态发生可挽回的错误,如读取到EOF字符等进行置位
badbit 当流发生不可挽回的错误时进行置位
eofbit 当读取到终止符EOF时进行置位

注意:当在读取到EOF将eofbit进行置位时,failbit也会进行置位

template <typename T>
void showState(T& ss) {
	cout << "goodbit:" << ss.good() << endl;
	cout << "failbit:" << ss.fail() << endl;
	cout << "eofbit:" << ss.eof() << endl;
	cout << "badbit:" << ss.bad() << endl;

}

另外 clear函数可以将已经发生损坏了 的流进行恢复。


三.指针偏移

1.seekg 与 tellg:
这两个函数都是针对于输入流的操作
seekg函数官方解释为:

basic_istream& seekg( pos_type pos );

表示从ios::beg,也就是开始的位置往后偏移pos个单位

basic_istream& seekg( off_type off, std::ios_base::seekdir dir);

off:为偏移量,为正时表示向后偏移,为负时表示向前偏移
dir:为起始位置,分为 ios::beg ios::cur ios::end 三种

tellg函数官方解释为:

pos_type tellg();

表示返回目前流指针的位置,注意是输入流的指针,当读取失败时返回-1
如下为测试用例:

//测试seekg与tellg,在已经读到流末尾不进行clear的情况
void test1() {
	istringstream iss("hello World");
	cout << "tellg:" << iss.tellg() << endl;
	string s;
	iss >> s;
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	cout << "-----------------------------------------" << endl;

	iss >> s;
	cout << "s:" << s << endl;//此时因为已经读到了EOF,eofbit 和 failbit都已经置位,tellg读取失败会返回-1
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	

}


//测试seekg与tellg,当流读到末尾进行clear的情况
void test2() {
	istringstream iss("hello World");
	cout << "tellg:" << iss.tellg() << endl;
	string s;
	iss >> s;
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	cout << "-----------------------------------------" << endl;

	iss >> s;
	iss.clear();//注意这里clear的作用是将各个bit位复原
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	cout << "-----------------------------------------" << endl;

	iss.seekg(0);
	//iss.seekg(3, ios::beg);//可以随意操作seekg最流指针的偏移进行操作
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);

}

tellp与seekp: seekp的官方文档:
basic_ostream& seekp( pos_type pos );
basic_ostream& seekp( off_type off, std::ios_base::seekdir dir );

tellp的官方文档:

pos_type tellp();

这两个的使用原理与seekg 与 putg相似,就不再做过多阐述

测试用例如下:

//测试 seekp 与 tellp
void test3() {
	ostringstream oss;
	string s("Hello World");
	oss << s;
	cout << "tellp:" << oss.tellp() << endl;
	showState(oss);
	cout << "-----------------------------------------" << endl;

	oss.seekp(0, ios::end);
	cout << "tellp:" << oss.tellp() << endl;
	showState(oss);
	cout << "-----------------------------------------" << endl;

}

练习:圣经文件的改写与统计

题目:
1.将《The_Holy_Bible.txt》文件中标点全部替换成空格,并将所有大写字母改为小写字母,保存到 《The_Holy_Bible_Res.txt》文件中.
2.统计《The_Holy_Bible_Res.txt》文件中字符、单词、行数并统计前十个出现频率最高的单词,并且打印出现频率。

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!