Day_10 IO流

本文详细介绍了C++中的输入输出流,包括iostream库中的标准流对象如cin、cout、cerr和clog,以及如何进行文件重定向。同时,讲解了字符流sstream的使用,特别是istringstream、ostringstream和stringstream的功能及操作。此外,还讨论了文件流的打开、关闭、读写方法以及文件指针的定位。文章最后提到了二进制读写和文件指针在文件操作中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.输入输出流

 

        流:若干个字符从一端到另一端我们叫做流。

输入流:istream类   

输出流:ostream类

        输出流的对象有三种。

预先定义的三个输出流对象

  • cout 标准输出,可以文件重定位(从文件中读取数据)
  • cerr 标准错误输出,没有缓冲,发送给他的内容立即输出,不能文件重定位
  • clog 类似于cerr,但是有缓冲,缓冲区满时被输出,可以文件重定位

 解释一下文件重定向:通过freopen函数重定位输出输入流。

    freopen("1.txt", "r", stdin);
    int a, b;
    cin >> a >> b;         //从1.txt中读取数据,并赋值

    freopen("2.txt", "w", stdout);        

    cout<<a+b<<endl;     //把a+b的结果输入到2.txt中

    clog<<a+b<<endl;     //和clog一样 可以重定向输入输出 cerr不行

输入输出的成员函数

  • cin的成员函数
    • get 函数
      • cin.get(‘ a ’)   //字符处理函数 获取一个字符a,返回值为获取的字符
      • char c=cin.get(‘ a ’)
    • getline() 函数
      • cin.getline(str,20)  //字符串处理函数,获取20个字符并赋值到str字符数组中
      • 处理的必须是字符串(char*) ,string类型不能处理
  • cout的成员函数
    • put 函数
      • cout.put(ch)        //字符输出函数,只能输出字符,这里ch是一个char类型变量
    • write 函数
      • cout.write(str,20)        //字符串处理函数,输出指定长度字符串(char* 类型)

格式控制字符( 包含头文件 iomanip)

  • 常用的格式控制,一种是调用成员函数方式,一种流控制字符去做
    •   设置有效位数: setprecision(n)
    •   设置精度: fixed结合setprecision使用

setiosflags 操纵符

  • 这个程序中,通过使用带参数的 setiosflags 操纵符来设置左对齐,setiosflags 定义在头文件 iomanip
  • 参数ios_base::leftios_base静态常量,因此引用时必须包括ios_base::前缀。
  • 这里需要用resetiosflags操纵符关闭左对齐标志。setiosflags不同于width和setw,它的影响是持久的,直到resetiosflags重新恢复默认为止
  • setiosflags 的参数是该流的格式标志值,可用按位或 (|) 运算符进行组合

精度

  • 浮点数输出精度默认值是6,例如:3466.98
  • 要改变精度:setprecision操作符(定义在iomanip中)
  • 如果不指定fixed或scientific,精度值表示有效数字位数
  • 如果设置了ios_base::fixed或ios_base::scientific精度值表示小数点之后的位数

//精度

double pi = 34.12343;
    cout << "设置有效位数是:" << setprecision(4) << pi << endl;        //一共四位数
    cout << "有效小数位:" << fixed << setprecision(4) << pi << endl;        //小数点后四位数

//进制输出
    cout << hex << 32 << endl;  //十六进制
    cout << oct << 15 << endl;  //8进制输出
    cout << setbase(10) << 15 << endl; //8-16

这里写图片描述

 cout << setiosflags(ios::left);    //ios::right    设置左对齐(右对齐)

 cout << resetiosflags << endl;        //可以通过resetionsflags来重置格式标识

2.字符流

        用的是头文件:sstream类

  • istringstream类 (输入流)

  • ostringstream类 (输出流)

  • 一般用时stringstream类对象即可  (既可输入又可输出,综合了上述两种)

  • 获取字符流对象中的数据

    • string str() //获取string

    • void str(const string& str); 重新设置字符流对象的数据

 

  两种创建字符流对象并赋值的操作

    stringstream sso(string("ILoveyou"));
    cout << sso.str() << endl;        //通过str成员函数输出 流对象中的字符串

    //或者构建无参字符流对象
    stringstream ssnull;
    ssnull<<"iLoveYou"<<endl;        //通过流运算符流入对象
    cout << ssnull.str() << endl; 
    //没有等号直接赋值的写法
    //stringstream ss = string("iLoveYou");

通过str成员函数的重写来修改流对象中的字符串

   stringstream sso(string("ILoveyou"));
    cout << sso.str() << endl;        //通过str成员函数获取流对象中的字符串
    sso.str("xxLL");                  //通过void str(const string& str); 重新设置字符流对象的数据
  • 一般字符流对象做字符串处理

    • 字符串分割:示例 分割23,132,3443,54,54,65

stringstream sData("23,123,5,454,7,388"); 
	int data[6];
	char cData[5];
	for (int i = 0; i < 6; i++){
		if (i == 5){
			sData >> data[i];
		}
		else
		//流入一个到整型数组  再流入一个到字符数组
		sData >> data[i] >> cData[i];
	}

 

  • 字符串转换数字问题

                具体:创建流对象 把字符或者数字流入对象,然后再作相应的输出。

//字符串与数字之间转换
    //数字转字符
	int num = 1234;
	char input[20] = "";
	stringstream transs(input);
	transs << num;
	transs >> input;
	cout << input << endl;

    //字符转数字
	stringstream snum("12345");
	int temp = 0;
	snum >> temp;
	cout << temp << endl;

3.文件流

头文件: #include <fstream>

        文件输入流:istream类

        文件输出流:ostream类

        综合输入输出流:fstream

打开关闭文件

  • 打开文件: void open(const char* URL,ios::openmode mode);

  • 关闭文件: void close()

    • 读写方法(ios::openmode)

      • ios::in 读的方式打开文件

      • ios::out 写方式打开文件 具有创建功能

      • ios::app 追加模式 具有创建功能呢

      • ios::ate 追加模式,文件指针指向末尾

      • ios::trunc 具备创建功能(一般组合使用)

      • ios::nocreate 不具备创建(一般组合使用)

      • ios::noreplace 不替换,保留文件原内容 (一般组合使用)

      • ios::binary 二进制的形式(一般组合使用)

  • 读写的组合方式用的是 |

    • 可读可写可创建: ios::in | ios::out | ios::trunc

    • 二进制的可读可写课创建: ios::in | ios::out | ios::trunc | ios::binary

  • 文件指针定位

    • 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);

    • 一般直接使用 fstream 类,对象即可使用 seekg ,也可使用 seekp

    • ios_base::seekdir (本质是枚举类型)

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

      • ios::end 文件结束位置

      • ios::cur 文件当前位置

 

         判断文件是否打开成功

	fstream file;
	//调用成员函数打开文件
	file.open("1.txt", ios::in);

	//1.判断文件是否成功(调用成员函数)
	if (!file.is_open()) {
		cout << "打开文件失败" << endl;
	}
	//2.判断文件是否成功(运算符重载)
	if (!file) {
			cout << "打开文件失败" << endl;
	}
	//调用成员函数关闭文件
	file.close();

文件读写的两种方式:1.流读写

                                    2.二进制读写

注意 用下面这种流操作符对文件输入输出时,会有一个弊端:输入时会跳过空格和换行符。

    fstream read(readFileName, ios::in);
	fstream write(writeFileName, ios::out);
	//成员函数eof() 判断是否在文件末尾
	//注意 这种<< >>流入流出的方法没法获取文件中的空格和换行 原理类似于cin遇到空格和换行表示输入结束
	while (1) {
		char key;
		read >> key;
		if (read.eof()) {
			break;
		}
		write << key;
	}

用get() put()的成员方法就不会有这样的弊端

	//用get() put()成员函数方法则没有这个弊端
	while (1) {
		char key;
		key = read.get();
		if (read.eof()) {
			break;
		}
		write.put(key);
	}

        上面是通过字符一个一个输入输出流,也可以通过字符串一个个输入输出文件流。

输入流通过对象调用成员函数 getline() 来读取字符串(一行一行读取),输出流通过成员函数 write() 来写入字符串。

        注:默认的 getline() 遇到”\n“才停止,且”\n“不会被接受

    fstream read(readFileName, ios::in);
	fstream write(writeFileName, ios::out);
	//上述两种都是以字符的形式读取
	//下面以字符串的形式读取
	while (1) {
		char str[1024] = "";
		read.getline(str, 1024);	//getline() 一行一行读取 不设定终止符默认为"\n"  遇到"\n"停止 但"\n"不会被存储
		if (read.eof()) {
			break;
		}
		write.write(str, strlen(str));

	}
	read.close();
	write.close();

 

        以上都是流的方式读写。流的方式读写需要注意用流运算符时的弊端,而二进制读写就没这么多问题了。二进制通过read()  和 write() 方法来读写

//二进制直接读取写入  不需要考虑这么多问题
	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();

 

文件指针

  • 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 文件当前位置

fstream readFile(readFileName, ios::in);
	fstream writeFile(writeFileName, ios::out);
	readFile.seekg(2, ios::beg);	
	char key = readFile.get();		//读取的是文件指针后面的那个字符
	writeFile.put(key);

	readFile.seekp(-3, ios::end);
	key = readFile.get();	
	writeFile.put(key);

	readFile.seekg(1, ios::cur);
	key = readFile.get();
	writeFile.put(key);

	readFile.close();
	writeFile.close();

注:读取是从文件指针后面一个字符开始读取的。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值