IO:向设备输入数据和输出数据
C++的IO流;
设备
- 文件
- 控制台
- 特定的数据类型(string)
读写文件:文件流
头文件:
类库: ifstream ofstream fstream
写文件:
#include <iostream>
#include <fstream>
using namespace std;
/*
需求:让用户输入姓名和年龄,并保存在文件中,直到用户输入ctrl+z结束
*/
int main(void)
{
// 输出到文件
ofstream ofs;
string name;
int age;
ofs.open("text.txt", ios::app);
if (ofs.fail())
cout << "文件打开失败" << endl;
while (1)
{
cout << "请输入姓名:" ;
cin >> name;
cout << "请输入年龄:";
cin >> age;
ofs << name << "\t";
ofs << age << "\n";
if (cin.eof())
{
break;
}
}
ofs.close();
return 0;
}
输出流会将变量输出到文件文件,也就是写操作;
读文件:
#include <iostream>
#include <fstream>
int main(void)
{
std::string name;
int age;
std::ifstream ifs;
// 以读得的方式打开文件;
ifs.open("text.txt", std::ios::in);
while (1)
{
ifs >> name >> age;
std::cout << name << "\t " << age << std::endl;
if (ifs.eof())
break;
}
ifs.close();
return 0;
}
可以看出ifstream和ofstream和标准输入输出流的使用非常相似,因为它们的继承关系;
二进制读取和写入文件
- 其实和文本文件的操作相似,只是读取和写入的方式不同;
std::ios::binary
#include <iostream>
#include <fstream>
int main(void)
{
std::string name;
int age;
std::ofstream ofs;
ofs.open("user.dat", std::ios::binary | std::ios::out | std::ios::trunc);
while (1)
{
std::cout << "请输入姓名:";
std::cin >> name;
if (std::cin.eof())
break;
std::cout << "请输入年龄:";
std::cin >> age;
ofs << name << "/t";
/*ofs << age << std::endl;*/
// 如果以整数方式写入文件,则不会改变
ofs.write((char*)&age, sizeof(age));
}
ofs.close();
return 0;
}
使用stringstream读取指定格式的字符串
格式化写入文件
使用stringstream先封装好在进行写入:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main(void)
{
string name;
int age;
ofstream ofs;
ofs.open("data.txt", ios::out | ios::trunc);
while (true)
{
// 使用stringstream特定格式写入
stringstream s;
cout << "请输入姓名[输入ctrl+Z退出]:";
cin >> name;
if (cin.eof())
break;
cout << "请输入年龄:";
cin >> age;
// 对字符串进行封装
s << "姓名:" << name << "\t\t\t年龄:" << age << endl;
ofs << s.str();
}
ofs.close();
return 0;
}
指定格式读取字符串(使用sscanf_s()注意这是c的方式要使用c的字符串)
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
using namespace std;
int main(void)
{
// data.tx
string linedata;
// 这里定义c的字符串供sscanf_s使用
char name[32];
int age;
ifstream ifs;
ifs.open("data.txt");
while (true)
{
getline(ifs, linedata);
if (ifs.eof()) break;
sscanf_s(linedata.c_str(), "姓名:%s 年龄:%d", name, sizeof(name), &age);
cout << "姓名:" << name << "\t\t\t年龄:" << age << endl;
}
ifs.close();
system("pause");
return 0;
}
文件流的定位
seekg
seekg(off_type offset // 偏移量
ios::seekdir origin) // 起始位置
/*
作用:设置输入流的位置
参数1:偏移量
参数2:相对位置
beg:相对于开始位置
cur:相对于当前位置
end:相对于结束位置
===========================================================
当前位置回退10个位置写法
seekg(-10,s.cur);
*/
tellg
返回该输入流的当前位置(距离文件的起始位置的偏移量),和seekg组合使用
案例:获取文件的长度:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
long long getFilelength(string filepath)
{
ifstream ifs;
ifs.open(filepath);
if (!ifs.is_open())
return 0;
ifs.seekg(0, ifs.end);
long long ret = ifs.tellg();
ifs.close();
return ret;
}
int main(void)
{
cout << "文件大小为:" << getFilelength("main.cpp");
system("pause");
return 0;
}
seekp
设置该输入流的位置
案例:先向文件中写入"123456789",然后再第4个字符位置写入ABC,替换"567";
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
ofstream ofs;
ofs.open("data.txt", ios::out | ios::trunc);
if (!ofs.is_open())
cout << "文件打开失败" << endl;
ofs << "123456789";
ofs.seekp(4, ofs.beg);
ofs << "ABC";
system("pause");
return 0;
}
小总结
seekg和tellg使用在ifstream输入流,读取文件使用,而seekp是使用ofstream写入文件使用,这一点区别开;