1.什么是IO流
- 流是若干个字节组成的字节序列,简单来说指的是就是数据从一端到另一端
- 键盘到程序——>标准输入流
- 程序到屏幕——>标准输出流
- 程序到文件——>文件流
- 流类体系:一些体系管理输入和输出的流的操作
- 输入流
- 输出流
- 文件流
ios
类
istream
ifstream
istringstream
ostream
ofstream
ostringstream
istream和ostream----->iostream
ifstream和ofstream---->fstream
- 所有流操作都可以采用**>> <<**运算完成输入的流动操作
2.C++输入输出流
- No.1 输入输出流对象
cin
标准输入,可以被重定向cout
标准输出,可以被重定向cerr
标准错误,必须要输出到屏幕,不可以被重定向clog
标准错误,输出到屏幕,可以被重定向- No.2 输入输出流对象对于字符具有成员函数的调用方式
- 字符
get()
输入字符put()
输出字符- 字符串
getline()
输入字符串writer()
输出字符串- No.3 流控制字符(C++流控制字符类似于C语言的转义字符 控制格式,比较鸡肋)
- 必须包含头文件
#include<iomanip>
- 流控制字符有两种形态,一个是成员函数的方式,一个是类似关键字的方式—>下面介绍类似关键字的方式
setbace()
按照不同的进制输出十进制数—–>支持八、十、十六进制setprecision()
设置有效位数
- 要控制小数位,需要结合
fixed
setw()
设置数据宽度setiosflags()
设置对其方式
ios::left
ios::right
put_time
格式时间格式—>如下表
specifier | Replaced by | Example |
---|---|---|
%a | Abbreviated weekday name * | Thu |
%A | Full weekday name * | Thursday |
%b | Abbreviated month name * | Aug |
%B | Full month name * | August |
%c | Date and time representation * | Thu Aug 23 14:55:02 2001 |
%C | Year divided by 100 and truncated to integer (00-99 ) | 20 |
%d | Day of the month, zero-padded (01-31 ) | 23 |
%D | Short MM/DD/YY date, equivalent to %m/%d/%y | 08/23/01 |
%e | Day of the month, space-padded ( 1-31 ) | 23 |
%F | Short YYYY-MM-DD date, equivalent to %Y-%m-%d | 2001-08-23 |
%g | Week-based year, last two digits (00-99 ) | 01 |
%G | Week-based year | 2001 |
%h | Abbreviated month name * (same as %b ) | Aug |
%H | Hour in 24h format (00-23 ) | 14 |
%I | Hour in 12h format (01-12 ) | 02 |
%j | Day of the year (001-366 ) | 235 |
%m | Month as a decimal number (01-12 ) | 08 |
%M | Minute (00-59 ) | 55 |
%n | New-line character ('\n' ) | `` |
%p | AM or PM designation | PM |
%r | 12-hour clock time * | 02:55:02 pm |
%R | 24-hour HH:MM time, equivalent to %H:%M | 14:55 |
%S | Second (00-61 ) | 02 |
%t | Horizontal-tab character ('\t' ) | `` |
%T | ISO 8601 time format (HH:MM:SS ), equivalent to %H:%M:%S | 14:55:02 |
%u | ISO 8601 weekday as number with Monday as 1 (1-7 ) | 4 |
%U | Week number with the first Sunday as the first day of week one (00-53 ) | 33 |
%V | ISO 8601 week number (00-53 ) | 34 |
%w | Weekday as a decimal number with Sunday as 0 (0-6 ) | 4 |
%W | Week number with the first Monday as the first day of week one (00-53 ) | 34 |
%x | Date representation * | 08/23/01 |
%X | Time representation * | 14:55:02 |
%y | Year, last two digits (00-99 ) | 01 |
%Y | Year | 2001 |
%z | ISO 8601 offset from UTC in timezone (1 minute=1, 1 hour=100) If timezone cannot be termined, no characters | +100 |
%Z | Timezone name or abbreviation * If timezone cannot be termined, no characters | CDT |
%% | A % sign | % |
测试代码
#include<iostream>
#include<iomanip>
#include<ctime>
using namespace std;
int main()
{
#if 0
cerr << "标准错误,不可以被重定向" << endl;
clog << "标准错误,可以被重定向" << endl;
cout << "字符输入:" << endl;
char key = cin.get();
cout.put(key);
setbuf(stdin, nullptr); //清空缓冲区操作
cout << "字符串输入:" << endl;
char buffer[20] = "";
cin.getline(buffer, 20); //优点在于可以设置长度
cout.write(buffer, 20);
#endif
//进制
cout << setbase(16) << 16 << endl;
cout << setbase(8) << 16 << endl;
cout << hex << 16 << endl; //16进制
cout << oct << 16 << endl; //8进制
cout << dec << 16 << endl; //10进制
//精度控制
double pi = 3.1415926535;
cout << pi << endl;
cout << setprecision(4) << pi << endl; //4位有效位数
cout <<fixed<< setprecision(4) << pi << endl; //结合fixed,4位小数
cout.unsetf(ios::fixed); //取消fixed
cout << pi << endl;
//制表 输入数据宽度+对齐方式
cout << setiosflags(ios::left);
cout << setw(6) << "姓名" << setw(6) << "年龄" << setw(6) << "学号" << endl;
cout << setw(6) << "张飞" << setw(6) << 18 << setw(6) << 1001 << endl;
cout << setw(6) << "关羽" << setw(6) << 28 << setw(6) << 1002 << endl;
cout << setw(6) << "刘备" << setw(6) << 38 << setw(6) << 1003 << endl;
//时间
time_t num = time(nullptr); //获取时间
tm* timeData = localtime(&num); //加载时间
cout << put_time(timeData, "%F %r") << endl; //输出时间
return 0;
}
测试结果
3.推荐查阅网站
https://cplusplus.com/reference/
这里是分类的,查阅c/c++都比较方便,网站是英文的,大家可以翻译一下
4.c++字符流
- 字符流头文件
#include<sstream>
,都存在一个宽字节版本的格式istringstream
ostringstream
- 一般处理字符流的是使用的类是
stringstream
string str()
获取字符流的字符串void str(const string& str)
重置stringstream
对象中的数据- 应用场景
- 数据的类型转换
- 字符串的切割
综合代码
#include<sstream>
#include<iostream>
#include<string>
using namespace std;
int main()
{
#if 0
stringstream object;
object << "king";
cout << object.str() << endl; //获取字符流中的字符串
char buffer[1024] = "";
object >> buffer; //object中的字符串流向buffer
cout << buffer << endl;
#endif
//No.1 数据的转换
int data = 1234;
string name = to_string(data);
cout << name << endl;
//easyx不能输出数字,数字转字符串
cout << "................" << endl;
//计算器
int res = 0; //字符串转数字
stringstream translate;
string str = "12345";
translate << str; //先把字符串流到translate
translate >> res; //再从translate中流到res中
cout << res << endl;
//No.2 数据分割
stringstream ip("192.168.1.1");
int ipnum[4];
char key[3];
for (int i = 0; i < 4; i++)
{
ip >> ipnum[i];
if( i < 3 ) ip >> key[i];
}
for (int i = 0; i < 4; i++)
{
cout << ipnum[i] << "\t";
}
cout << endl;
//注意:一个流做类型转换,多次一定要clear清除
res = 0;
string temp = "88888";
translate.clear(); //并不是清除,是指针的移动
translate << temp;
translate >> res;
cout << res << endl;
//清除
stringstream test("kkkkkkkk");
test.str("");
//test.clear();
cout << test.str() << endl;
return 0;
}
测试结果
5.c++文件流
1.文件流类
fstream
读写操作ofstream
写操作 ouput:打印 打印东西到文件就是写操作ifstream
读操作 input:把文件当作输入的地方#include<fstream>
- 打开文件:
void open(const char* URL,ios::openmode mode)
ios::in
读ios::out
写 具有创建功能ios::app
追加模式 具有创建功能ios::ate
打开已有文件 文件指针在文件末尾ios::trunc
文件不存在具有创建文件功能ios::binary
二进制ios::nocreate
不创建ios::replace
不做替换- 组合方式
ios::in|ios::out
ios::in|ios::trunc
ios::in|ios::binary|ios::trunc
- 文件关闭:
void close()
- 文件状态函数
- 文件为空
bool is_open()
返回false打开文件失败,true是成功- !文件流对象
int eof()
判断是否到达文件末尾
综合代码
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
class File
{
public:
File(string name="",int age=0,int num=0):name(name),age(age),num(num){}
void print()
{
cout << name << "\t" << age << "\t" << num << endl;
}
string& getName() { return name; }
int& getAge() { return age; }
int& getNum() { return num; }
void saveFile(const char* filename)
{
fstream file;
file.open(filename, ios::out);
if(!file)
{
cout << "打开文件失败" << endl;
return;
}
//流方式写数据,尽量写空格和换行,便于作为读出来的格式数据的风格
file << name << " " << age << " " << num << " " << endl;
file.close();
}
void readFile(const char* filename)
{
fstream file(filename, ios::in);
if (!file)
{
cout << "打开文件失败" << endl;
return;
}
file >> this->name >> this->age >> this->num;
file.close();
}
protected:
string name;
int age;
int num;
};
//字符读写,ASCII码读写
void asciiReadwrite(const char* readfile,const char* writefile)
{
fstream read(readfile, ios::in);
fstream write(writefile, ios::out);
if(!read||!write)
{
cout << "打开文件失败" << endl;
return;
}
while (!read.eof())
{
char key;
read.get(key);
write.put(key);
}
read.close();
write.close();
}
//二进制读写
void binaryReadwrite(const char* readfile, const char* writefile)
{
fstream in(readfile, ios::in | ios::binary);
fstream out(writefile, ios::out | ios::binary);
if (!in || !out)
{
cout << "打开文件失败" << endl;
return;
}
while (!in.eof())
{
char key[1024] = "";
in.read(key, 1024);
out.write(key, strlen(key) + 1);//要有效长度,否则多出的会都用空格写上
}
in.close();
out.close();
}
int main()
{
File file("king", 18, 1001);
file.saveFile("1.txt");
File x;
x.readFile("1.txt");
x.print();
asciiReadwrite("1.txt", "2.txt");
binaryReadwrite("1.txt", "3.txt");
return 0;
}
2.c++文件指针
ifstream
对象ifstream& seekg(long int pos);
ifstream& seekg(long int pos,ios::base::seekdir begin);
ofstream
对象ofstream& seep(long int pos);
ofstream& seep(long int pos,ios::base::seekdir begin);
seekdir
ios::beg
开始的位置ios::end
结束的位置ios::cur
当前位置
void testseekReadfile(const char* filename)
{
fstream read(filename, ios::in);
if (!read) { cout << "打开文件失败" << endl; return; }
read.seekg(3, ios::beg);
char key = read.get();
cout << key << endl;
read.seekg(-3, ios::end);
char k = read.get();
cout << k << endl;
read.close();
}