C++文件读取
#include <fstream>
三个类:
类名 (默认的方式)
读 ifstream ios::in
写 ofstream ios::out
读/写 fstream ios::in | ios::out
openmode 打开模式说明
ios::in 以读取方式打开文件
ios::out 以写入方式打开文件
ios::app 每次写入数据时,先将文件指针移到文件尾,以追加数据到尾部(append)
ios::ate 进初始时将文件指针移到文件尾,仍可以在任意位置写入数据(at end)
ios::trunc 写入数据前,先删除文件原有内容(清空文件),当文件不存在时,会创建文件
ios::binary 以二进制方式打开文件,不作任何字符转换
文件操作三部曲:
1.打开
2.读取
3.关闭
文件 读/写:文件打开后,就可对文件进行读/写操作,分为【文本方式】读/写 和【二进制方式】读/写。
【文本方式】在读写过程中会对字符进行转换或删去某些字符(如空格字符等),一般适用于有一定数据格式的文件读取。
【二进制方式】则按照字节进行读写,不作任何数据转换,读取的数据不会丢失。
利用重载的 "<<" 操作符写入文件
1 /* 解释: 2 重载的 "<<" 和 ">>" 操作符也可用来操作文件数据。 3 ofstream "<<" 操作符将数据 【写入】流 4 ifstream ">>" 操作符从文件流中【取出】数据,每次取出的数据默认由空格符分开。 5 */ 6 7 //-------------------------------------------------- 利用重载的 "<<" 操作符写入文件 8 #include <fstream> 9 #include <iostream> 10 using namespace std; 11 int main(void) 12 { 13 ofstream wFileStream; 14 //----------------1. 打开 15 // app 方式写入文件。。。每次写入数据时,先将文件指针移到文件尾,以追加数据到尾部(append) 16 wFileStream.open("D:\\水果.txt", ios::out | ios::app); 17 if (!wFileStream) 18 { 19 cout << "打开文件失败!" << endl; 20 return 1; 21 } 22 23 //---------------2. 读写 24 wFileStream << "apple" << " " << "苹果" << endl; 25 wFileStream << "banana" << " " << "香蕉" << endl; 26 wFileStream << "grape" << " " << "葡萄" << endl; 27 28 //---------------3. 关闭 29 wFileStream.close(); 30 31 return 0; 32 }
利用重载的 ">>" 操作符读出文件
1 //-------------------------------------------------- 利用重载的 ">>" 操作符读出文件 2 #include <fstream> 3 #include <iostream> 4 using namespace std; 5 void main() 6 { 7 ifstream rFileStream; 8 //------------------1.打开 9 rFileStream.open("D:\\水果.txt", ios::in); 10 if(!rFileStream) 11 { 12 cout << "打开文件失败" << endl; 13 } 14 15 //------------------2.读/写 16 // 读文件 17 char eName[10], cName[10]; 18 19 rFileStream >> eName >> cName; 20 cout << eName << ' '<< cName <<endl; 21 22 rFileStream >> eName >> cName; 23 cout << eName << ' '<< cName <<endl; 24 25 rFileStream >> eName >> cName; 26 cout << eName << ' '<< cName <<endl; 27 28 rFileStream >> eName >> cName; 29 cout << eName << ' '<< cName <<endl; 30 rFileStream >> eName >> cName; 31 cout << eName << ' '<< cName <<endl; 32 rFileStream >> eName >> cName; 33 cout << eName << ' '<< cName <<endl; 34 35 //------------------3.关闭 36 rFileStream.close(); 37 38 }
逐字符读取文件
1 /* 解释: 2 对文件数据进行单字节(即一个字符大小)读写,可使用 ifstream 类的 get 函数和 ofstream 类的 put 函数。 3 这些函数会将文件的所有字符(包括不可显示字符)都读出来。 4 ifstream& get(char& c) 5 ofstream& put(char& c) 6 */ 7 8 //-------------------------------------------------- 逐字符读取文件 9 #include <fstream> 10 #include <iostream> 11 using namespace std; 12 int main() 13 { 14 ifstream rFileStream; 15 rFileStream.open("D:\\水果.txt", ios::in | ios::binary); 16 if(!rFileStream) 17 { 18 cout << " 打开文件失败 " << endl; 19 return 1; 20 } 21 22 char c; 23 // 未到达文件尾 24 while (!rFileStream.eof()) 25 { 26 // 逐字符读出 27 rFileStream.get(c); 28 // 控制台输出字符 29 cout << c; 30 } 31 32 rFileStream.close(); 33 34 return 0; 35 }
多字节数据的读写
1 /* 解释: 2 一次读写多个字节数据到文件,可考虑使用 ifstream 类的 read 函数和 ofstream 类的 write 函数。 3 这两个函数的参数 buf 是读写缓冲区,参数 n 是读写的字节数目 4 ifstream& read(char* buf, streamsize n) 5 ofstream& write(const char* buf, streamsize n) 6 */ 7 // 文件读写都没有问题。问题是,手动打开那个student.txt文件的时候,有乱码 8 9 //-------------------------------------------------- 多字节数据的读写 10 #include <fstream> 11 #include <iostream> 12 using namespace std; 13 struct Student 14 { 15 char name[8]; 16 int year; 17 }; 18 19 int main () 20 { 21 Student st; 22 strcpy(st.name, "宋公明"); 23 st.year = 18; 24 // 写入 25 ofstream wFileStream; 26 wFileStream.open("D:\\student.txt", ios::out); 27 if (!wFileStream) 28 { 29 cout << "打开文件失败" << endl; 30 return 1; 31 } 32 //reinterpret_case<char*>(&st) 将st类型【强制转换】为 char* 类型。 33 wFileStream.write(reinterpret_cast<char*>(&st), sizeof(Student)); 34 wFileStream.close(); 35 36 // 读取 37 ifstream rFileStream; 38 rFileStream.open("D:\\student.txt", ios::in); 39 rFileStream.read(reinterpret_cast<char*>(&st), sizeof(Student)); 40 cout << st.name << " " << st.year << endl; 41 rFileStream.close(); 42 43 return 0; 44 }
读一行数据
1 /* 解释: 2 读取文件数据的另一种常用函数是 ifstream::getline 函数,当该函数读取到 n 个字节数据,或遇到默认的换行符 "\n", 3 又或者已到达文件尾部时返回。参数 buf 是读写缓冲区,参数 delim 用于设定换行符 4 ifstream& getline(char* buf, streamsize n) 5 ifstream& getline(char* buf, streamsize n, char delim) 6 */ 7 8 //-------------------------------------------------- 读一行数据 9 #include <fstream> 10 #include <iostream> 11 using namespace std; 12 int main() 13 { 14 ifstream rFileStream; 15 // rFileStream.open("D:\\水果.txt", ios::in); 16 rFileStream.open("D:\\student.txt", ios::in); 17 if (!rFileStream) 18 { 19 cout << "打开文件失败" << endl; 20 return 1; 21 } 22 23 char str[30]; 24 rFileStream.getline(str, 30); 25 cout << str; 26 rFileStream.close(); 27 28 return 0; 29 }
随机读取文件数据
1 /* 解释: 2 利用 ifstream 类的 seekg 函数和 ofstream 类的 seekp 函数,可移动文件的读写指针,进行文件的随机访问操作。 3 这两个函数分别从 istream 和 ostream 类继承过来。使用原型如下。 4 ifstream& seekg(off_type offset, seekdir origin) 5 ofstream& seekp(off_type offset, seekdir origin) 6 seekp 函数的后缀 "g" 是 "get pointer" 的头字母,表明了函数将文件【读指针】移到 offset 偏移位置处,origin 为偏移的起始位置。 7 seekp 函数的后缀 "p" 是 "put pointer" 的头字母,表明了函数将文件【写指针】移到 offset 偏移位置处,origin 为偏移的起始位置。 8 参数类型 off_type 实际是一个整数类型, seekdir 类型是一个枚举类型, origin只能取值 ios::beg ios::cur ios::end 9 分别表示从文件起始位置、当前文件读写位置、文件结束位置 索引偏移值。(索引值从 0 开始计算,不是从 1 开始计算) 10 11 类似的函数有 tellg/tellp ,可分别获取当前文件指针的读位置和写位置。 12 例如,如下两行代码先将文件指针移到文件结束处,然后用 tellg 函数再取得当前文件指针位置值,即为文件大小。 13 rwFileStream.seekg(0, ios::end); // 移动到文件结束位置 14 int filesize = rwFileStream.tellg(); 15 */ 16 17 //-------------------------------------------------- 随机读取文件数据 18 #include <fstream> 19 #include <iostream> 20 using namespace std; 21 int main() 22 { 23 fstream rwFileStream; 24 rwFileStream.open("d:\\digit.txt", ios::in | ios::out | ios::binary | ios::trunc); 25 if (!rwFileStream) 26 { 27 cout << "打开文件失败" << endl; 28 return 1; 29 } 30 31 // 写入 26 个字母 32 for (char i=0; i<26; i++) 33 rwFileStream << char('a'+i); 34 // 定位到第 3 个字符。(从 0 索引) 35 rwFileStream.seekg(3, ios::beg); 36 char c; 37 rwFileStream.get(c); 38 // 打印出字符 d 39 cout << c << endl; 40 rwFileStream.close(); 41 42 return 0; 43 }