文件流、指针偏移、流状态位与圣经文件练习
一.文件流
在文件流中, 定义的类型有:
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》文件中字符、单词、行数并统计前十个出现频率最高的单词,并且打印出现频率。
来源:CSDN
作者:Worthy_Wang
链接:https://blog.csdn.net/Worthy_Wang/article/details/104013923