C++ IO流 day9

IO流

  • 流:若干个字节组成的字节序列
    • 设备 ->程序(stdin)
    • 程序 ->设备(stdout)
    • 程序 ->文件(文件流)
  • 流管理体系:输入输出流,字符流,文件流

标准输入输出流

  • 流对象的类型:运算符重载中
  • 输入输出对象:
cincoutcerrclog
标准输入标准输出标准错误标准错误
可被重定向可被传重定向不可重定向可重定向
  • 流对象调用成员函数方式:字符和字符串输入方式
    • get():输入字符
    • put():打印字符
    • getline():输入字符串
    • write():打印字符串
#include <iostream>
#include <string>
int main()
{
	std::clog << "clog" << std::endl;
	std::cerr << "cerr" << std::endl;
	//输入字符
	char str = std::cin.get();
	//打印字符
	std::cout.put(str);
	std::cout << std::endl;
	//清空缓冲区,\n
	while (std::cin.get() != '\n');
	//输入字符串,可以带空格
	char s[20]="";
	std::cin.getline(s, 20);
	std::cout << s << std::endl;
	//打印字符串,可以控制打印数量
	std::cout.write(s,8);
	return 0;
}
  • 运行结果
    在这里插入图片描述
  • 流控制字符:类似与C语言的格式控制字符
    • 头文件包含:#include <iomanip>
    • 流控制字符基本上都有一个成员函数的方式
      • setbase:设置进制
      • setprecision():设置有效位数
        • 想要控制小数位,要结合fixed使用
      • setiosflags(ios::mode):设置对齐方式
        • ios::left
        • ios::right
      • setw():设置输出数据的宽度
    • 时间格式:put_time 格式化时间
#include <iostream>
#include<iomanip>
int main()
{
	//进制,无二进制打印方式
	std::cout <<"打印十六进制的15:" << std::setbase(16) << 15 << std::endl;
	std::cout << "打印十六进制的15:" << std::hex << 15 << std::endl;
	std::cout << "打印八进制的15:" << std::setbase(8) << 15 << std::endl;
	std::cout << "打印八进制的15:" << std::oct << 15 << std::endl;
	//设置了进制后记得设置回十进制方式
	std::cout << "打印十进制的15:" << std::setbase(10) << 15 << std::endl;
	std::cout << "打印十进制的15:" << std::dec << 15 << std::endl << std::endl;


	//精度控制,会默认四舍五入
	std::cout <<"控制前4位有效位:" << std::setprecision(4) << 123.4567 << std::endl;
	std::cout << "控制前4位小数有效位:" << std::fixed << std::setprecision(4) << 123.456789 << std::endl << std::endl;


	//制表,默认是右对齐,加了设置对齐方式就是所设置的对齐方式
	std::cout << "制表,默认是右对齐,加了设置对齐方式就是所设置的对齐方式" << std::endl;
	std::cout << std::setw(8) << "小瓜"
		<< std::setw(10) << 21
		<< std::setw(16) << 210591025
		<< std::endl;
	std::cout << std::setw(8) << "小瓜"
		<< std::setw(10) << 21
		<< std::setw(16) << 210591025
		<< std::endl << std::endl;
	std::cout << "加了左对齐后:" << std::endl;
	std::cout << std::setiosflags(std::ios::left)
		<< std::setw(8) << "小瓜"
		<< std::setw(6) << 21
		<< std::setw(6) << 210591025
		<< std::endl;
	std::cout << std::setiosflags(std::ios::left)
		<< std::setw(8) << "小瓜"
		<< std::setw(6) << 21
		<< std::setw(6) << 210591025
		<< std::endl << std::endl;

	//也可以调用成员函数的方式,基本上每个格式控制流都有一个成员函数例如;
	//std::cout.width(6); 等效与setw()
	//具体看官方手册有详细

	//时间格式
	time_t t = time(nullptr);
	tm* tmData = localtime(&t);
	std::cout << "当前日期时间:" << std::put_time(tmData, "%F %r") << std::endl;
	return 0;
}
  • 运行结果
    在这里插入图片描述

文件流

  • fstream类:可读可写
    • ofstream:写操作
    • ifstream:读操作
  • 使用的时候包含父类:#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 out | ios::binary
  • 关闭文件:void close()
  • 文件状态函数
    • 文件是否为空
      • bool is_open():返回false文件打开失败,true为成功
      • 取反文件对象操作也可以
    • 是否到达文件结束:int eof()
void openFile()
{
	std::fstream file;
	//一般就in out trunc三个一起
	file.open("xiaogua.txt", std::ios::in|std::ios::out|std::ios::trunc);
	//!file和!file.is_open()任用一个就行
	if (!file||!file.is_open())
	{
		std::cout << "打开文件失败" << std::endl;
	}
	else
	{
		//文件操作一定要使用后关闭文件
		file.close();
	}
}
  • 读写文件
    • 文件流对象结合>> <<完成读写
    • 字符的方式读写
      • get函数
      • put函数
    • 调用成员函数读写
      • read:读操作
      • write:写操作
#include <iostream>
#include <fstream>
#include <string>
//读写文件
class IOfile
{
public:
	IOfile(std::string name = "", int age = 0, int id = 0) :name(name), age(age), id(id) {}
	//文件保存操作
	void sevaFile(const char* fileName)
	{
		std::fstream file(fileName, std::ios::in | std::ios::out | std::ios::trunc);
		if (!file)
		{
			std::cout << "文件打开失败" << std::endl;
		}
		else
		{
			//写入文件操作尽量带空格和格式,方便读出,因为文件里面以空格为数据的结束
			file << name << " " << age << " " << id << std::endl;
			file.close();
		}
	}
	//文件的读入操作
	void readFile(const char* fileName)
	{
		std::fstream file(fileName, std::ios::in);
		if (!file)
		{
			std::cout << "文件打开失败" << std::endl;
		}
		else
		{
			file >> this->name >> this->age >> this->id;
			file.close();
		}
	}
	void print()
	{
		std::cout << name << " " << age << " " << id << std::endl;
	}
protected:
	std::string name;
	int age;
	int id;
};
int main()
{
	IOfile xiaogua("小瓜", 21, 10001);
	xiaogua.sevaFile("xiaogua.txt");
	IOfile test;
	test.readFile("xiaogua.txt");
	test.print();
	return 0;
}
  • 以字符或字符串的方式读写文件拷贝文件
#include <iostream>
#include <fstream>
#include <string>
//字符的方式读写文件拷贝文件
void copyFileByASCII(const char* readFile, const char* writeFile)
{
	std::fstream r(readFile, std::ios::in);
	std::fstream w(writeFile, std::ios::out);
	if (!r || !w)
	{
		std::cout << "打开文件失败" << std::endl;
	}
	
	以字符的方式读写
	//while (!r.eof())
	//{
	//	char key = r.get();
	//	w.put(key);
	//}
	//r.close();
	//w.close();

	//以字符串的方式读写
	char buf[1024] = "";
	r.getline(buf, 1024);
	//想写多少数据就写多长
	w.write(buf, strlen(buf));
	r.close();
	w.close();
}
int main()
{
	copyFileByASCII("xiaogua.txt", "dagua.txt");
	return 0;
}
  • 以二进制的方式读写拷贝文件
#include <iostream>
#include <fstream>
#include <string>
//字符的方式读写文件拷贝文件
void copyBinaryFile(const char* r, const char* w)
{
	std::fstream rFile(r, std::ios::in | std::ios::binary);
	std::fstream wFile(w, std::ios::out);
	if (!rFile || !wFile)
	{
		std::cout << "文件打开失败!" << std::endl;
	}
	else
	{
		while (!rFile.eof())
		{
			char buf[5] = "";
			//不能读满,读满不是一个字符串
			rFile.read(buf, 4);
			//写的长度就是实际长度,如果超出就会写空格进去
			wFile.write(buf, strlen(buf));
		}
		wFile.close();
		rFile.close();
	}
}
int main()
{
	copyBinaryFile("xiaogua.txt", "dashagua.txt");
	return 0;
}
  • 文件指针移动
    • ifstream类对象
      • ifstream& seekg(long int pos);
      • ifstream& seekg(long int pos,ios::base::seekdir pos);
    • ofstream类对象
      • ofstream& seekg(long int pos);
      • ofstream& seekg(long int pos,ios::base::seekdir pos);
    • ios::base::seekdir
      • ios::beg 开始位置
      • ios::end 结束位置
      • ios::cur 当前位置
#include <iostream>
#include <fstream>
#include <string>
//文件指针移动
void seekFile(const char* fileName)
{
	std::fstream r(fileName, std::ios::in);
	if (!r)
	{
		std::cout << "文件打开失败!" << std::endl;
	}
	else
	{
		//寻找6这个位置的数据
		r.seekg(6);
		std::cout << (char)r.get() << std::endl;
		//寻找倒数第二个位置数据
		r.seekg(-2, std::ios::end);
		std::cout << (char)r.get() << std::endl;
		r.close();
	}
}
int main()
{
	seekFile("xiaogua.txt");
	return 0;
}

字符流

  • 字符流头文件:sstream
    • istringstream
    • ostringstream
  • 一般使用stringstream
  • string str():获取字符流对象中的字符串
  • void str(const string& str):重置字符流对象中的字符串
#include <iostream>
#include <sstream>

int main()
{
	std::stringstream str;
	str << "xiaogua";
	char buf[1024] = "";
	str >> buf;
	std::cout << buf << std::endl;
	std::cout << str.str() << std::endl;
	char temp[1024] = "dagua";
	str.str(temp);
	std::cout << str.str() << std::endl;
	return 0;
}
  • 运行结果
    在这里插入图片描述

  • 一般使用场景:

    • 字符串切割
    • 数据的类型转换
#include <iostream>
#include <sstream>
struct Date
{
	int year;
	int month;
	int day;
};
int main()
{
	//数字转字符串
	int num = 123;
	std::cout << std::to_string(num) << std::endl;
	//字符串转数字,一个字符流多次做类型转换时,一定记得clear清除
	std::stringstream temp;
	std::string str = "123";
	int result = 0;
	temp << str;
	temp >> result;
	std::cout << result << std::endl;
	//做数据分割
	std::stringstream info("2023 年 8 月 1 日");
	struct Date date;
	std::string value;
	info >> date.year;
	info >> value;
	info >> date.month;
	info >> value;
	info >> date.day;
	info >> value;
	std::cout << date.year << " " << date.month << " " << date.day << std::endl;
	std::cout << info.str() << std::endl;
	return 0;
}
  • 运行结果
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值