Day 10 IO流及文件操作

一、基本概念:

1.流:若干字节数据从一端到另一端的过程

2.流类体系:流对象,流运算符 << 和 >>

二、输入输出流:

1.ostream类:cout、cerr(仅此一个不可以重定向为文件)、clog

补充:重定向freopen的使用:

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

void test_freopen()
{
	freopen("1.txt", "r", stdin);//in输入
	int a, b;
	scanf("%d%d", &a, &b);//输入由文件完成
	cout << a << "\t" << b<<endl;
	freopen("2.txt", "w", stdout);
	printf("%d", a + b);
}
int main()
{
	test_freopen();
	return 0;
}

A.字符类的处理:

        ①cout.put('a');//调用成员函数

        ②cout.write("i love you ",4);//从左边截取输出

        ③c=cin.get()//输入一个字符

        ④有关getline():

char str[20]="";
while(cin.get('\n')!='\n')//清空缓冲区和回车,防止影响到下面行的读取
{
    cin.getline(str,20);
}

B.格式控制字符:包含头文件<iomanip> 

        常用的格式控制,一种是流控制字符去做(一般都会对应到一个成员函数),一种是调用成员函数的方式。

格式:①设置有效位数:setprecision(n);

           ②设置精度,fixed结合setprecision使用(四舍五入)

cout<<"设置有效位数是:"<<setprecision(4)<<变量名<<endl;
cout<<"有效小数位:"<<fixed<<setprecision(4)<<变量名<<endl;
void test_iomanip()
{
	cout << "有效位数为:" << setprecision(4) << 4.25546333 << endl;
	cout << 12345.0 << endl;//输出12345
//cout<<fixed<<setprecision(2)<<123.456<<endl;/*如果在这个位置就加上fixed的话,后面的输出全部都按照fixed处理*/
	cout << setprecision(4) << 3.1415926 << endl;//输出的结果是3.142
	cout << setprecision(3) << 12345.0 << endl;//输出的结果是 "1.23e+004 "
	cout << fixed << setprecision(2) << 123.456 << endl;//输出的结果是123.46,要进行四舍五入
	cout << showpoint << 12345.0 << endl;//输出12345.00
	cout << "有效小数位数为:" << fixed << setprecision(4) << 4.25546333 << endl;
}

注意:若前面cout含有fixed那么之后无需加上fixed的setprecision都默认是控制有效的小数位数。

进制 : hex 十六进制   oct 八进制  dec 十进制 setbase()->括号只可以在8.10.16中选择

             setw( )输入一个width,数据不够就用空格站位'\t'->默认右对齐

指表:修改为左对齐:  cout<<setiosflags(ios::left);

       取消,恢复默认:     cout<<resetiosflags<<endl; 

void test_Jinzhi()
{
	cout << dec << 2321<<endl;
	cout << hex << 9233 << endl;
	cout << oct << 3214 << endl;
	cout << setbase(16) << 15 << endl;
	cout << setiosflags(ios::left) << setw(8) << 123<<endl;
	cout << setw(8) << 123<<endl;
	cout << resetiosflags(ios::left) << setw(8) << 123;
}

2.istream类   cin

三、字符流

头文件<sstream>类

注:把string写到文件,需要先转换为char* 在写进去。

1.istringstream类和ostringstream类------->一般用stringstream类对象就行(好用)。

2、成员函数  对象.str()

        //例:构建字符流对象,以及获取字符流对象中的数据。

void test_sstream()
{
	//法一:
	stringstream sso(string("wbm"));
	cout << sso.str() << endl;
	//错误写法:stringstream  sso=string("wbm");
	//法二:
	stringstream ssnull;//先定义
	ssnull << "wbb";//流进去 ,此处可以不用string()类型转换
	string data;
	ssnull >> data;
	ssnull.str("");//清除操作
	cout << data << endl;
}

3、一般字符流对象做字符处理:

        ①字符串转换问题:字符串和数字的转换

                1.  数字转成字符串 c库有atoi()函数    c++可用to_string()

                                此处直接用流对象转换(注意:流对象在前面)

void transfer_str()
{
	int num = 123;
	char input[20] = "";
	stringstream s(input);
	s << num;
	s>>input;//一定是流对象在前!
	cout << input << endl;
}

                  2.字符串转换成数字:

void transfer_num()
{
	stringstream  str("666");
	int temp = 0;
	str >> temp;
	cout << temp << endl;
}

        ②字符串的分割问题: (还有其他5种方法,见收藏夹)

void seperate_str(int *a,char*b,int num,const char*p)
{
	stringstream  sso(p);
	for (int i = 0; i < num; i++)
	{
		if (i == num - 1)
		{
			sso >> a[i];//这里流对象必要用char *初始化,才能够进行流操作
		}
		else
		{
			sso >> a[i] >> b[i];
		}
	}
}
int main()
{
	int a[10];
	char b[10];
	seperate_str(a, b, 5, "1,2,55,66,74844");
	for (int j = 0; j < 5; j++)
	{
		cout << a[j]<<"  ";
	}
	return 0;
}

4、关于如何清除stringstream对象的值:(方法如下)

stringstream abc("213");
abc.str("");

注:clear不是清除的意思,理解为“重置状态更为合适”,多次同一个流做数据类型转换操作,一定要做clear操作。(比如 上3的两个函数如均在main函数中实现,是要clear一下的,否则会有问题) 

四、文件流

1.流类体系:①ofstream类写操作 output 输出到文件

                      ②ifstream类 读操作 

                       ③fstream类 可读可写

(头文件:<fstream>)

2.打开关闭文件:(均为成员函数)

                ①打开文件:原型

void open(const chat* URL,ios::openmode mode,int access);

 

当然也可以直接初始化:

#include<fstream>
fstream read(readFileName,ios::in);

        几个openmode ios::out(写的方式打开,可以创建文件)            ​​​​​  ios::in(读的方式打开)       ios::trunc(创建)   ios::app(追加,可创建)       ios::ate(打开已有文件,指针指向文件末尾)

ios::_Nocreate(不创建文件)      ios::_Noreplace(不替换文件)   ios::binary(二进制方式打开)

           几个mode的组合方式:用按位或 | 去连接                

                                ①可读可写可创建(顺序随意)

ios::in|ios::out|ios::trunc

                                ②二进制可读可写可创建

ios::in|ios::out|ios::trunc|ios::binary

        判断文件是否打开成功:

        ①用文件流对象重载的非运算!

        ②is_open成员函数:返回true  打开成功

void openfile()
{
	fstream a;
	a.open("1.text", ios::app);
	if (!a)
	{
		cout << "open failure" << endl;
		return;
	}
	if (!a.is_open())
	{
		cout << "open failure" << endl;
		return;
	}
}

3.读写方式:

读一个文件通常用eof()判断是否读到了结尾(注意eof读到最后返回-1 为真)

        ①流方式读写:

                A:字符(文件1流出来,再留到文件2)

                                可能会产生两个问题:1.eof会多读一次(解决:放好eof的位置,如下)

                                                                    2.空格和回车会被忽略(见第二版)

第一版本:(无法处理\n和空格)用的流

void ascii_Readchar()
{
	fstream c("1.txt",ios::in);
	fstream p("2.txt", ios::out);
	if (!c)
	{
		cout << "open failure" << endl;
		return;
	}
	if (!p.is_open())
	{
		cout << "open failure" << endl;
		return;
	}
	while (1)
	{
		char ch;
		c>>ch;
		if (c.eof())//注:若文件指针读到了最后,最终返回的是一个-1 即为真!!!!
		{
			break;
		}
		p<<ch;
	}
	p.close();
	c.close();
}

第二版本:(用get() put()) 

void ascii_Readchar()
{
	fstream c("1.txt",ios::in);
	fstream p("2.txt", ios::out);
	if (!c)
	{
		cout << "open failure" << endl;
		return;
	}
	if (!p.is_open())
	{
		cout << "open failure" << endl;
		return;
	}
	while (1)
	{
		char ch;
		c.get(ch);
		if (c.eof())//注:若文件指针读到了最后,最终返回的是一个-1 即为真!!!!
		{
			break;
		}
		p.put(ch);
	}
	p.close();
	c.close();
}

                 B.getline(char* str,int )和write(char* ,int)组合(不自带换行)

                                write的后一个参数最好用strlen(str)小心多出来的空行

void ascii_Readchar()
{
	fstream c("1.txt", ios::in);
	fstream p("2.txt", ios::out);
	if (!c)
	{
		cout << "open failure" << endl;
		return;
	}
	if (!p.is_open())
	{
		cout << "open failure" << endl;
		return;
	}
	while (!c.eof())
	{
		char str[1024];
		c.getline(str,1024);
		p.write(str, strlen(str));
		p.put('\n');
	}
	p.close();
	c.close();
}

                ②二进制方式读写

void binaryRWFile(const char* readFileName, const char* writeFileName)
{
	fstream readFile(readFileName, ios::in | ios::binary);
	fstream writeFile(writeFileName, ios::out | ios::binary);
	while (!readFile.eof())//块读写
	{
		char str[1024] = "";
		readFile.read(str, 1024);
		writeFile.write(str, 1024);
	}
	readFile.close();
	writeFile.close();
}

 4.文件指针定位:

  • ifstream类的对象

    • istream& seekg(long int pos);

    • istream& seekg(long int pos,ios_base::seekdir position);

  • ofstream类的对象

    • ostream& seekp(long int pos);

    • ostream& seekp(long int pos,ios_base::seekdir position);

  • ios_base::seekdir

    • ios::beg 文件开始位置 //SEEK_SET

    • ios::end 文件结束位置

    • ios::cur 文件当前位置

(注:long int pos 是从当前位置为0,以负数为例,向上找到第四个元素

          ios_base::seekdir position是一个枚举类型,代表三个位置之一指定! )

void testSeekRead(const char* fileName) 
{
	fstream fread(fileName, ios::in);
	if (!fread) 
	{
		cout << "打开文件失败!" << endl;
	}
	char key = fread.get();
	cout << key;
	fread.seekg(4,ios::beg);
	key = fread.get();
	cout << key;
	fread.seekg(-4, ios::end);
	key = fread.get();
	cout << key << endl;
	fread.close();
}

( 注:fstream的文件指针可以用ifstream 类的也可以ofstream类的)

                                                

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值