c++ 流与文件


课件来自武汉大学夏启明老师

类层次,标准输入输出,非格式化输入输出

在这里插入图片描述

  • 非格式化的输出指按系统预定义的格式进行输入和输出
  • 在这里插入图片描述
    -在这里插入图片描述

格式化输入输出

常用要求

需求 操作 说明
固定一位小数 cout<<fixed<<setprecision(1) << num; fixed, setprecision 在头文件iomanip中
输入一行 string str;
getline(cin, str);
#include<string>

通用规则

主要有三类格式控制操作

  • 第一类:使用cout.flags(…) 或 cout.setf(…)
    flags()原型:
fmtflags flags() const;
fmtflags flags (fmtflags fmtfl);

setf() 原型

fmtflags setf (fmtflags fmtfl);
fmtflags setf (fmtflags fmtfl, fmtflags mask);

控制符和mask:

fmtfl format flag value mask field bitmask
left, right or internal adjustfield
dec, oct or hex basefield
scientific or fixed floatfield
   long f = cout.flags();
   cout.setf(ios::showpos | ios::scientific);
   cout.unsetf(ios::showpos);
   cout.flags(ios::hex)
  • 第二类,使用cout的成员函数,如cout.width(…), cout.presicion(…)
   // 设置及获取宽度, 设置仅一次有效, 默认0
   cout.width(10);
   int width = cout.width();
   // 设置及获取填充
   cout.fill('*');
   char fillchar = cout.fill();
   // 精度,设置后一直有效,默认6
   cout.presicion(8);
  • 第三类,使用操作符函数 , 如setw()
   // 用操作符函数格式化   #include <iomanip.h>
   cout<<setw(5)<<setfill('*')<<setpresicion(8)<<num<<end;
   cout<<setiosflags(ios::fixed);
   int num = 100;
   cout<<dec<<num<<hex<<num<<oct<<num;
   cint>>ws>>c;   // ws 取消输入结束符函数

自定义操作符函数

// 用户自定义操作符函数
ostream & setup(ostream & stream){
		stream.setf(ios::left);
		stream<<set(8)<<setfill('*');
		return stream;
}
int main(){
		cout<<10<<setup<<10;
}

用户自定义输入输出

  • 重载<<, >>
#include<iostream>
#include<string>
using namespace std;
struct Student{
	int id;
	string name;
	friend ostream& operator<<(ostream &stream, const Student&s);
	friend istream& operator>>(istream &stream,Student &s);
};

ostream& operator<<(ostream &stream, const Student&s){
	stream<<"id:"<<s.id<<endl;
	stream<<"name:"<<s.name<<endl;
	return stream;
}
istream& operator>>(istream &stream,Student &s){
	cout<<"input id and name"<<endl;
	stream >> s.id>>s.name;
	return stream;
}
int main(){
	Student s;
	cin>>s;
	cout<<s;
	return 0;
}

文件输入输出

流种类

ifstream in;
ofstream out;
fstream both;

打开流

  • 有两种方式打开流,一是使用open函数,原型为
    void open(const unsigned char *, int mode, int access=filebuf::openrot);
    mode值决定文件如何被打开
mode 说明
ios::app 输出追加到文件尾部
ios::ate 文件指针移到文件尾部
ios::trunk 若文件存在,则先删除后新建(默认)
ios::io
ios::out
ios::nocreate 若文件不存在,则打开失败
ios::replace 若文件存在,则打开失败
ios::binary 以二进制方式打开,默认以文本形式打开

access 值决定文件访问方式,也就是文件类别

类别
0 普通文件
1 只读文件
2 隐含文件
4 系统文件
8 备份文件

第二种打开文件的方式:直接将参数传给构造函数,不需要使用open()

#include<fstream>
#include<iostream>
#include<string>
using namespace std;

int main(){
	string line;
	// 输入 
	ifstream istrm;
	istrm.open("paradigm.cpp");
	while(istrm>>line){
		cout<<line<<endl;
	}
	istrm.close();

	ofstream ostrm("text.txt",ios::app); 
	ostrm<<"// hello world"<<endl;
	ostrm.close();
	return 0;
}

文本文件的读写

  • 使用<< >>
  • get(), put()
  • write(), read()

二进制文件的读写

  • get(), put()

  • write(), read()
    原型

istream& read(unsigned char * buf, int num);
ostream& write(const unsigned char* buf, int num);

打开失败与关闭流

  • 如果打开失败,返回值是0
ofstream out("file.txt");
if(!out){
	cout<<"can't open file"<<endl;
	return -1;
}
  • 关闭流: f.close();

判断文件是否结束

  • 方法一:ifs.eof() 返回非0表示到达文件末尾
  • 方法二:流对象是否为0,0表示文件结束

随机读写文件

C++的I/O系统里有个文件指针,它有两个名字。一个名字叫get指针,用于指出下一次输入操作的位置。另一个叫put指针,用于指出下一次输出操作的位置。

  • 在顺序访问时,每当发生一次输入或输出错做,文件指针自动连续增加。而使用seekg()和seekp()可以使用非连续的方式访问文件,原型如下
ostream& seekp(streampos pos);
ostream& seekp(streamoff off, ios::seek_dir dir);
istream& seekg(streampos pos);
istream& seekg(streamoff off, ios::seek_dir dir);
  • 其中streampos和streamoff都等效于long类型。
  • dir取值:
含义
ios::beg 文件头
ios:cur 当前位置
ios::end 文件尾

例:将第5个字符替换成*

	fstream fs("text.txt", ios::in| ios::out);
	if(!fs){
		cout<<"open file fail."<<endl; exit(1);
	}
	fs.seekp(4,ios::beg);
	fs.put('*');
	fs.seekg(0,ios::beg);
	char buf[100];
	fs.get(buf,100);
	cout<<buf<<endl;
发布了56 篇原创文章 · 获赞 2 · 访问量 521

猜你喜欢

转载自blog.csdn.net/qq_41956860/article/details/102780987