(八)IO类

IO类

1.应用以及相应头文件

  • 操纵char字符
  • 读写命名文件
  • 处理string类型
  • 宽字符语言使用,定义一组类型和对象操纵wchar_t,相比与char型,类型定义前缀里加了w。比如wcin、wcout等。

相应IO库头文件和类型如下:

头文件类型
iostreamistream,wistream 从流中读数据
ostream,wostream 从流中写数据
iostream,wiostream 读写流
fstreamifstream,wifstream 从文件中读数据
ofstream,wofstream 从文件中写数据
fstream,wfstream 读写文件
sstreamistringstream,wistringstream 从string中读数据
ostringstream,wostringstream 从string中写数据
stringstream,wstringstream 读写string

2.类型之间关系

设备类型和字符大小不会影响我们要执行的IO操作,这些操作的操作方法一致。能忽略不同流类型之间差异的原因是继承机制

3.IO对象公共操作

IO对象不能拷贝赋值

  • 不能拷贝赋值,不能作为形参或返回类型。
  • 可以通过引用方式传递或者返回流,引用不能是const类型。

访问和操纵流的条件状态

状态类型

其中strm是一种IO类型。

类型说明
strm::iostate提供表达流状态完整功能,作为一个位集合使用。
strm::badbit流已崩溃,发生系统级错误,流无法被使用,badbit置位时failbit也会置位
strm::failbit一个IO操作失败,可恢复错误
strm::eofbit流达到文件结束,eofbit和failbit同时置位
strm::goodbit流未处于错误状态,此值一直为零
流状态查询函数
函数说明
s.bad()badbit置位,返回true
s.fail()failbit置位,返回true
s.eof()eofbit置位,返回true
s.good()s有效状态,返回true,所有错误均未置位
s.rdstate()返回当前状态条件,返回值类型strm::iostate
//查询流没有出错的几种方法:
while(cin>>word){}
if(!cin.fail()){}
if(cin.good()){}
管理状态函数
函数说明
s.clear()所有条件状态位复位
s.clear(flags)流中对应条件位复位
s.rdstate()返回当前状态条件
管理输出缓冲
输出缓冲
  • 每个输出流关联一个缓冲区,保存程序读写数据,程序正常结束,return操作结束时缓冲刷新会被执行。如果程序崩溃,缓冲区不会被刷新,数据可能会停留在输出缓冲区。
  • 当缓冲区满,需要刷新缓冲;
刷新缓冲方式
  • 使用操纵符可以显式刷新缓冲区;
	cout << 1 << endl;  //换行并刷新缓冲区
	cout << 1 << flush;	//刷新缓冲区
	cout << 1 << ends;	//插入空字符,刷新缓冲区
	cout<<unitbuf; //所有输出操作后会立即刷新缓冲区
	cout<<noununitbuf; //回到正常缓冲方式
	cerr<<1; //cerr设置为unitbuf,写到cerr的内容是立刻刷新的。
  • 关联输出流与另一个流
    当一个流与输出流关联在一起。以输入流为例,从输入流读取数据的操作会刷新关联的输出流。标准库将cin和cerr与cout关联在一起,读cin或者写cerr都会导致cout缓冲区刷新。
cin>>ival; //cout缓冲区刷新

通过tie可以将一个流与输出流进行关联,tie有两个版本,一个返回指向输出流的指针,一个接收指向输出流的指针,指针可以为空(nullptr)。

	cout << &cout << endl;  //&cout
	cout << cin.tie() << endl;	//&cout
	ostream* oldtie = cin.tie(nullptr);
	cout << oldtie<< endl;  //&cout
	cout << cin.tie() << endl; //nullptr
	cin.tie(&cerr);
	cout << cin.tie() << endl; //&cerr
	cin.tie(oldtie);
	cout << cin.tie() << endl; //&cout

文件输入输出

文件类型

头文件类型
fstreamifstream,wifstream 从文件中读数据
ofstream,wofstream 从文件中写数据
fstream,wfstream 读写文件

文件操作

函数及类型含义
构造fstream fstrm;创建未绑定文件流
fstream fstrm(s);创建文件流并打开
fstream fstrm(s,mode);按指定模式打开文件
打开fstrm.open(s);打开文件并与fstrm绑定,返回void。
关闭fstrm.close()关闭与fstrm绑定的文件,返回void。
是否打开成功fstrm.is_open()返回bool值,检查文件是否打开并且尚未关闭
class hhdy {
public:
	friend istream& read(istream& is, hhdy& hh);
	friend ostream& print(ostream& os, hhdy& hh);
private:
	char h1[10];
	char h2[10];
};
istream& read(istream& is, hhdy& hh) {
	is >>hh.h1 >> hh.h2;
	return is;
}
ostream& print(ostream& os, hhdy& hh) {
	os << hh.h1<<endl;
	os << hh.h2 << endl;
	return os;
}

int main( ) {
	vector<string> argv(4);
	argv[0] = "F:\\c++\\Project1\\IO类\\1.txt";
	argv[1] = "F:\\c++\\Project1\\IO类\\2.txt";
	argv[2] = "F:\\c++\\Project1\\IO类\\3.txt";
	argv[3] = "F:\\c++\\Project1\\IO类\\4.txt";
	
	ifstream wfile(argv[0]);
	hhdy hh;
	read(wfile, hh);
	wfile.close();

	for (int i = 1; i < 4; ++i) {
		ofstream rfile(argv[i]); //对于路径下不存在的文件会自己创造一个文件
		if (rfile.good()) {  //判断是否打开,可替换rfile.is_open(),!rfile.fail(),rfile.good()
			cout << "open the file[" << i << "] successful"<<endl;
			print(rfile, hh);
		}
		else {
			cerr << "Can't open the file!" << endl;
		}
	}	//对于循环内创建并打开的文件流,离开作用域后文件自动关闭
	return 0;
}

文件模式

文件模式含义
in以读方式打开,ifstream、fstream
out以写方式打开,ofstream,fstream
app写操作前定位到文件末尾,trunc没被设定时可以设定app模式。app模式下,文件总是以输出方式被打开
ate打开操作后立即定位到文件末尾,不限制文件流类型和文件模式
trunc截断文件,截断即清空文件内容重新输入,out被设定时trunc才能被设定,out默认为trunc模式
binary以二进制方式进行IO,不限制文件流类型和文件模式
int main() {
	string s;
	vector<string> argv(4);
	argv[0] = "F:\\c++\\Project1\\IO类\\1.txt";
	argv[1] = "F:\\c++\\Project1\\IO类\\2.txt";
	argv[2] = "F:\\c++\\Project1\\IO类\\3.txt";
	argv[3] = "F:\\c++\\Project1\\IO类\\4.txt";

	fstream wfile(argv[0]);
	wfile << argv[0];
	//wfile >> s;  这样写无值,因为定位到了文件末尾
	wfile.close();
	wfile.open(argv[0], ofstream::in);  //隐含截断
	wfile >> s;
	wfile.close();

	wfile.open(argv[1],ofstream::out);  //隐含截断
	wfile << s;
	wfile.close();

	wfile.open(argv[2], ofstream::out|ofstream::trunc);  //显式截断
	wfile << s;
	wfile.close();

	wfile.open(argv[3], ofstream::app);  //不截断
	wfile <<'\n';
	wfile << s;
	wfile.close();

	wfile.open(argv[3], ofstream::out|ofstream::ate);  //定义ofstream::out时,下述程序会截断
	wfile << '\n';
	wfile << s;
	wfile.close();

	wfile.open(argv[3], ofstream::ate);  //没定义ofstream::out时,下述程序无变化?
	wfile << '\n';
	wfile << s;
	wfile.close();

	wfile.open(argv[3], ofstream::out | ofstream::binary);  //没定义ofstream::out时,下述程序无变化?
	wfile << '\n';
	wfile << s;
	wfile.close();

	return 0;
}

string流

头文件类型
sstreamistringstream,wistringstream 从string中读数据
ostringstream,wostringstream 从string中写数据
stringstream,wstringstream 读写string

string流操作

函数及类型含义
构造sstream fstrm;创建未绑定string流
sstream fstrm(s);创建string流并绑定s
返回fstrm.str();返回strm保存的string拷贝
拷贝fstrm.str(s)将s拷贝到strm中,返回void。
bool valid(const string &num) {
	//位数判断、是否是数字等
	for (const auto s : num) {
		if(!isdigit(s))
		{
			return false;
		}
	}
	return true;
}
struct PersonInfo {
	string name;
	vector<string> phones;
};

int main() {
	string line, word;
	vector<PersonInfo> people;
	while (getline(cin, line)) {
		PersonInfo info;
		istringstream record(line);
		record >> info.name;
		while (record >> word)
			info.phones.push_back(word);
		people.push_back(info);
	}

	for (const auto& entry : people) {
		ostringstream formatted, badNums;
		for (const auto& nums : entry.phones) {
			if (!valid(nums)) {
				badNums << " " << nums;
			}
			else {
				formatted << " " << nums;
			}
		}
		if (badNums.str().empty()) {
			cout << entry.name << ":" << formatted.str() << endl;
		}
		else {
			cerr << "error in "<<entry.name << ":" << badNums.str() << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值