目录
0.前言
对文件流的读写
文件打开方式:
1.写文本文件
2.读文本文档
2.1使用efo函数判断出现数据被读取两次
3.二进制方式写文件
4.二进制读文件
5.按指定格式读写数据stringstream
0.前言
对文件流的读写
ifstream 对文件输入(读文件)
ofstream 对文件输出(写文件)
fstream 对文件输入或输出
文件打开方式:
ios::in |
读方式打开文件 |
ios::out |
写方式打开文件 |
ios::trunc |
如果此文件已经存在, 就会打开文件之前把文件长度截断为0 |
ios::app |
尾部最加方式(在尾部写入) |
ios::ate |
文件打开后, 定位到文件尾 |
ios::binary |
二进制方式(默认是文本方式) |
以上打开方式, 可以使用位操作 | 组合起来。
1.写文本文件
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
int main() {
ofstream ofs; //也可以使用fstream ,但是fstream默认打开方式不截断文件长度
//ofstream 的默认打开方式是截断式写入 ios::out|ios::trunc
//fstream 的默认打开方式是截断写入 ios::out
//建议指定打开方式
ofs.open("temp.txt",ios::out|ios::trunc);
string name;
int age;
while (1) {
cout << "请输入姓名([ctrl]+z退出):" ;
cin >> name;
if (cin.eof()) {
break;
}
cout << "请输入年龄:" ;
cin >> age;
stringstream s;
s << name << '\t' << age<<'\n';
ofs << s.str();
}
ofs.close();
system("pause");
return 0;
}
运行截图:
打开temp.txt文档:
2.读文本文档
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
int main() {
ifstream ifs;
ifs.open("temp.txt");
string name;
int age;
while (1) {
if (ifs.eof()) {
break;
}
ifs >> name;
ifs>> age;
cout << name << '\t' << age << endl;
}
ifs.close();
cout << line << endl;
system("pause");
return 0;
}
运行结果:
由运行结果可知,文档的最后一行元素被读取两次,这是为什么呢?
2.1使用efo函数判断出现数据被读取两次
在使用C/C++读文件的时候,一定都使用过eof()这个函数来判断文件是否为空或者是否读到文件结尾了,大家可能有一个误区,认为eof()返回true时是读到文件的最后一个字符,其实不然,eof()返回true时是读到文件结束符0xFF,而文件结束符是最后一个字符的下一个字符。
这就是在判断文档是否为空时要先用char读取,再使用eof函数。
解决方法:
1.提前读取,再进行判断(注意要使用string类型读取)
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
int main() {
ifstream ifs;
ifs.open("temp.txt");
string name;
int age;
int line = 0;
while (1) {
ifs >> name;
if (ifs.eof()) {
break;
}
ifs>> age;
cout << name << '\t' << age << endl;
}
ifs.close();
system("pause");
return 0;
}
运行结果:
3.二进制方式写文件
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
string name ;
int age ;
ofstream ofs;
//.dat文件用记事本打开会是乱码
ofs.open("user.dat", ios::out | ios::trunc | ios::binary);
while (1) {
cout << "请输入姓名([ctrl]+z退出):";
cin >> name;
if (cin.eof()) {
break;
}
cout << "请输入年龄:";
cin >> age;
ofs << name << "\t";
//outfile << age << endl; //会自动转成文本(字符串)方式写入
ofs.write((char*)&age, sizeof(age)); //将age的地址转为char指针类型
}
ofs.close();
// 关闭打开的文件
ofs.close();
system("pause");
return 0;
}
使用notepad++查看运行后的二进制文件:
4.二进制读文件
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
int age;
//ifs>>age; temp是二进制存储,直接读取会以文本方式读出
//使用read读取会读取空格符\制表符.....
//ifs.read((char*)&age,sizeof(age));
ifstream ifs;
ifs.open("user.dat", ios::in | ios::binary);
while (1) {
ifs >> name;
if (ifs.eof()) { //判断文件是否结束
break;
}
cout << name << "\t";
// 跳过中间的制表符
char tmp;
ifs.read(&tmp, sizeof(tmp));
//infile >> age; //从文本文件中读取整数, 使用这个方式
ifs.read((char*)&age, sizeof(age));
cout << age << endl; //文本文件写入
}
// 关闭打开的文件
ifs.close();
system("pause");
return 0;
}
运行结果:
5.按指定格式读写数据stringstream
#include<fstream>
#include<string>
#include<iostream>
#include<sstream>
using namespace std;
//按指定格式写文件
void funWrite() {
string name = "凌云志";
int age =18;
ofstream ofs;
ofs.open("temp.txt");
stringstream s;
s << "姓名:" << name << "\t\t年龄:" << age << endl;
//把指定格式数据写入文件
ofs << s.str();
ofs.close();
}
//按指定格式读文件
void funRead() {
ifstream ifs;
ifs.open("temp.txt");
string line;
char name[32];
int age;
while (1) {
getline(ifs, line); //每次读取一行
if (ifs.eof()) { break; }
//按C语言格式将读取的一行转为char*数组格式(line.c_str())
//注意文档中的“:”冒号是中文还是英文
sscanf_s(line.c_str(), "姓名:%s 年龄:%d", name, sizeof(name), &age);
cout << "姓名:" << name << "\t\t年龄:" << age << endl;
}
ifs.close();
}
int main() {
funWrite();
funRead();
system("pause");
return 0;
}
运行结果以及文档截图: