文章目录
课件来自武汉大学夏启明老师
类层次,标准输入输出,非格式化输入输出
- 非格式化的输出指按系统预定义的格式进行输入和输出
-
格式化输入输出
常用要求
需求 | 操作 | 说明 |
---|---|---|
固定一位小数 | 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;