1:为了支持使用宽字符的语言,标准库定义了一组类型和对象来操作wchar_t类型的数据。宽字符版本的类型和函数的名字以w
开头。宽字符版本和普通的char版本定义在同一个头文件中,例如头文件fstream
定义了ifstream
和wifstream
。
2:标准库能使我们忽略不同类型流之间的差异是通过继承机制
实现的。
3:IO对象无拷贝或者赋值。所以我们不能将IO对象作为函数形参或者返回值,一般用引用
的形式。又因为读写IO操作会使得对象的状态发生变化,所以一般不会用const
类型的。
4:使用IO就伴随着可能发生错误的风险。下面是判断IO对象是否正常的条件状态。
IO | 含义 |
---|---|
strm::iostate | strm是一种IO类型,包括iostream,fstream,sstream等,iostate是一种机器相关的类型?什么叫机器相关? |
strm::badbit | 指流已经崩溃 |
strm::failbit | 指一个IO操作已经失败了 |
strm::eofbit | 指流到达了文件的末尾 |
strm::googbit | 指流未处于错误状态,此值保证为0 |
s.eof() | 若流s的eofbit置位,则返回true |
s.fail() | 若流s的failbit或者badbit置位,则返回true |
s.good() | 若流处于有效状态,则返回ture |
s.clear() | 将流的所有状态条件复位,将流的状态设置为有效,返回void |
s.clear(flags) | 根据给定的flags,将流s中对应条件复位,flags的类型为strm::iostate。返回void |
s.setstate(flags) | 根据给定的flags,将流s中对应条件复位,flags的类型为strm::iostate。返回void |
s.rdstate() | 返回流的当前状态,返回值类型为strm::iostate |
5:unitbuf和nounitbuf
unitbuf:所有输出操作后都会刷新缓冲区
nounitbuf:重置流,使其恢复正常使用的系统管理的缓冲区刷新机制。
需要注意的是:如果程序崩溃,输出缓冲区是一般不会被刷新的。
有关刷新的知识请看下面的例子:
#include<iostream>
#include<thread>
#include<chrono>
int main(int argc,char *argv[])
{
int a = 5;
std::cout << a << std::endl; //直接输出a的值,刷新了缓冲
std::cout << a << std::flush; //直接输出a的值,刷新了缓冲
std::cout << a << std::ends; //没有直接输出a的值,程序结束才输出
std::cout << a << std::unitbuf; //没有直接输出a的值,程序结束才输出
std::cout << a << std::nounitbuf;//没有直接输出a的值,程序结束才输出
//下面的代码是让程序sleep两秒。
for(int i = 2;i > 0; --i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
6:文件的输入输出
fstream中定义了三个类型来支持文件IO
ifstream:从一个给定文件中读取数据。
ofstream:向一个给定文件中写数据。
fstream:用来读写给定文件。
下面是fstream中的一些特有的操作:
名称 | 含义 |
---|---|
fstream fstrm | 创建一个未绑定的文件流。fstream是头文件fstream中定义的一个类型 |
fstream fstrm(s) | s是文件名,默认打开权限 |
fstream fstrm(s,mode) | 与前一个构造函数类似,但是按照指定的mode打开文件 |
fstrm.open(s) | 打开名为s的文件,并且将文件与fstrm绑定 |
fstrm.close() | 关闭与fstrm绑定的文件 |
fstrm.is_open() | 返回一个bool值,指出与fstrm相关联的文件是否打开且尚未关闭 |
7:使用c++读写文件
打开文件的几种模式:
模式 | 含义 |
---|---|
in | 以读方式打开 |
out | 以写方式打开 |
app | 以追加的方式打开 |
ate | 打开文件后立即定位到文件末尾,即使文件有内容也读不出来 |
trunc | 截断文件 |
binary | 以二进制的方式进行IO |
std::ifstream input(filename); //默认ifstream以in的模式打开文件
std::ofstream output(filename); //默认ofstream以out的模式打开文件
std::fstream fstrm(filename); //默认以in和out的模式打开文件
std::ofstream output(filename,std::ofstream::app) //以追加的方式打开
std::ifstream input(filename,std::ifstream::app) //默认打开文件失败则新建文件。
>> : 相当于cin()函数,由于它已经经过重载,我们可以直接使用,用于读文件。
<< : 相当于print()函数,重新写入文件
下面程序从一个文件读取数据存入另一个文件,文件名通过main函数的参数指定:
#include<iostream>
#include<fstream>
using std::cout;
using std::cin;
using std::endl;
int main(int argc,char *argv[])
{
std::ifstream input(argv[1]); //假设argv[1]是一个int类型的数据文件
std::ofstream output(argv[2],std::ofstream:;app); //第二个参数的意思是追加数据
if(input) {
int a;
while(input >> a) { //从argv[1]读取一个数据
output << a << " "; //将数据写入argv[2]中。
}
}
return 0;
//下面两句是必须的吗?
input.close();
output.close();
}
8:istringstream和ostringstream的用法
istringstream:
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<vector>
using std::cout;
using std::cin;
using std::endl;
struct people {
std::string name;
std::vector<std::string> phones;
};
int main(int argc,char *argv[])
{
std::vector<people> PersonInfo;
std::ifstream input("5.txt");
if(input) {
std::string line,word;
while(std::getline(input,line)) { //input从原文件中读取一行
people pop;
std::istringstream record(line);
//利用istringstream对整个line字符串构造,接下来处理的是读取的整行字符
record >> pop.name;
while(record >> word) {
pop.phones.push_back(word);
}
PersonInfo.push_back(pop);
}
}
std::ofstream output("6.txt");
for(auto u:PersonInfo) {
output << u.name << " ";
for(auto h:u.phones) {
output << h << " ";
}
output << endl;
}
return 0;
}
ostringstream用于当我们逐步构造输出,希望一并打印或者处理的时候比较有用。
对于ostringstram的使用我们可以使用<<
运算符,当我们使用其时,就相当于向定义的
ostringstream对象添加字符。