out.write,flush,cout格式化输出

本文介绍了C++中有关I/O流的操作,包括out.write的使用、如何刷新输出缓冲区以及cout的格式化技巧。通过设置字段宽度、填充字符、浮点数精度等,实现输出的精确控制。还提到了 endl 和 flush 控制符的作用,以及利用setf函数控制浮点数的小数点和末尾0的显示。

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

一些I/O类

在这里插入图片描述

out.wirte


//===============================================================
//FileName:
//          write.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

//using cout.write()

#include <iostream>

int main() {

	using std::cout;
	using std::endl;

	const char* state1 = "Florida";
	const char* state2 = "Kansas";
	const char* state3 = "Euphoria";

//------------------------------------------------------------------------

	int len = std::strlen(state2);
	cout << "Increasing loop index:\n";
	int i;
	for (i = 1; i <= len; i++)
	{
		cout.write(state2, i);//第一个参数指出要显示的字符串的地址,第二个参数指出要显示多少个字符
		cout << endl;
	}


//------------------------------------------------------------------------
	// concatenate output
	cout << "Decreasing loop index:\n";
	for (i = len; i > 0; i--)
		cout.write(state2, i) << endl;//cout.write返回cout对象,所以可以拼接


//------------------------------------------------------------------------
	// exceed string length
	cout << "Exceeding string length:\n";
	cout.write(state2, len + 5) << endl;
	//write方法并不会遇到空字符时自动停止打印字符,而只是打印指定数目的字符。
	//即使超过了字符串的边界!
	//超过后打印相邻的内存中的数据。

	return 0;


}

刷新输出缓冲区

  • 由于ostream类对cout对象处理的输出进行缓冲,所以输出不会立即发送到目标地址,而是被存储到缓冲区中,直到缓冲区填满,然后程序将刷新(flush)缓冲区,把内容发送出去,并清空缓冲区,以存储新的数据,通常,缓冲区为512字节或其整数倍,当标准输出连接的是硬盘上的文件时,缓冲可以节省大量的时间。
  • 对于屏幕输入
float num;
cout<<"Enter a number: ";
cin >> num;
  • 假设没这种特性,程序将等待输入,而无法通过cout消息来提示用户。
  • 如果实现不能在所希望时刷新输出,可以使用两个控制符中的一个来强行进行刷新。
  • endl 和flush可以强行进行刷新缓冲区
float num;
cout<<"Enter a number: "<<flush;

//或者
flush(cout);
//其实cout<<flush;就是重载以了以上 的方法

//或者
cout<<"Enter a number: "<<flush;//刷新加换行符
cin >> num;

cout进行格式化


//===============================================================
//FileName:
//          defaults.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

//cout default formats
#include <iostream>

int main() {
	using std::cout;
	cout << "12345678901234567890\n";

//------------------------------------------------------------------------

	char ch = 'K';
	int t = 273;

//------------------------------------------------------------------------

	cout << ch << ":\n";
	cout << t << ":\n";
	cout << -t << ":\n";

//------------------------------------------------------------------------

	double f1 = 1.200;
	cout << f1 << ":\n";
	cout << (f1 + 1.0 / 9.0) << ":\n";

//------------------------------------------------------------------------

	double f2 = 1.67E2;
	cout << f2 << ":\n";

	f2 += 1.0 / 9.0;

//------------------------------------------------------------------------

	cout << f2 << ":\n";
	cout << (f2 * 1.0e4) << ":\n";


//------------------------------------------------------------------------

	double f3 = 2.3e-4;
	cout << f3 << ":\n";
	cout << f3 / 10 << ":\n";



	return 0;
}

修改显示时使用的计数系统(二进制、十进制)


//===============================================================
//FileName:
//          manip.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// manip.cpp -- using format manipulators
#include <iostream>

int main()
{
	using namespace std;
	cout << "Enter an integer: ";
	int n;
	cin >> n;

	cout << "n     n*n\n";
	cout << n << "     " << n * n << " (decimal)\n";
	
	//dec十进制、hex十六进制、oct八进制

	// set to hex mode
	cout << hex; //被重载的原型函数为hex(count)
	cout << n << "     ";
	cout << n * n << " (hexadecimal)\n";

	// set to octal mode
	cout << oct << n << "     " << n * n << " (octal)\n";

	// alternative way to call a manipulator
	dec(cout);
	cout << n << "     " << n * n << " (decimal)\n";



	return 0;
}

调整字段宽度

cout << "#";
cout.width(12);
cout<<12<<"#"<<24<<"#\n";
  • 由于width是成员函数,必须使用 对象(这里为cout)来调用它。
  • 输出
#          12#24#
  • 12被放到宽度为12个字符的字段的最右边,这被称为右对齐,然后字段宽度恢复为默认值。
  • width()方法只影响接下来显示的一个项目,然后字段恢复到默认值。
  • c++不会截断数据,因此如果试图在宽度为2的字段中打印一个7位值,c++将增宽字段,以容纳该数据。


//===============================================================
//FileName:
//          width.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// width.cpp -- using the width method

#include <iostream>

int main()
{
	using std::cout;
	int w = cout.width(30);//width()方法只影响接下来显示的一个项目,然后字段恢复到默认值。
	//返回w为0,而不是30,因为返回的事以前的字段宽度,而不是刚设置的值,w为0表明,默认的字段宽度为0,由于c++总会增长字段,以容纳数据,因此这种值适用于所有的数据。
		//cout.width();返回字段宽度的当前设置
		//cout.width(int i);将字段设置为i个空格

	cout << "default field width = " << w << ":\n";

//------------------------------------------------------------------------

	cout.width(5);
	cout << "N" << ':';
	cout.width(8);
	cout << "N * N" << ":\n";

	for (long i = 1; i <= 100; i *= 10)
	{
		cout.width(5);
		cout << i << ':';
		cout.width(8);
		cout << i * i << ":\n";
	}
	// std::cin.get();
	return 0;
}

填充字符

  • 默认是以空格填充字段中未被使用的部分,可以用fill成员函数来改变填充字符cout.fill('*')
  • 与字段宽度不同,新的填充字符将一直有效,直到更改它为止

//===============================================================
//FileName:
//          fill.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// fill.cpp -- changing fill character for fields
#include <iostream>

int main()
{
	using std::cout;
	cout.fill('*');

//------------------------------------------------------------------------

	const char* staff[2] = { "Waldo Whipsnade", "Wilmarie Wooper" };
	long bonus[2] = { 900, 1350 };

//------------------------------------------------------------------------

	for (int i = 0; i < 2; i++)
	{
		cout << staff[i] << ": $";
		cout.width(7);
		cout << bonus[i] << "\n";
	}
	

	return 0;
}

设置浮点数的显示精度

cout.precision(2)

  • 新的精度设置将一直有效,直到被重新设置
  • c++默认的精度为6位,末尾的0将不显示。
  • 精度指小数点后面的位数

//===============================================================
//FileName:
//          precision.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// precise.cpp -- setting the precision
#include <iostream>

int main()
{
	using std::cout;
	float price1 = 20.40;
	float price2 = 1.9 + 8.0 / 9.0;

	cout << "\"Furry Friends\" is $" << price1 << "!\n";
	cout << "\"Fiery Fiends\" is $" << price2 << "!\n";

//------------------------------------------------------------------------

	cout.precision(2);
	cout << "\"Furry Friends\" is $" << price1 << "!\n";
	cout << "\"Fiery Fiends\" is $" << price2 << "!\n";

//------------------------------------------------------------------------

	return 0;
}

"Furry Friends" is $20.4!
"Fiery Fiends" is $2.78889!
"Furry Friends" is $20!
"Fiery Fiends" is $2.8!

C:\Users\sualab\source\repos\CPlusPlus\Debug\CPlusPlus.exe (进程 171660)已退出,返回代码为: 0。
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...

打印 末尾的0和小数点

  • iostream系列类没有提供专门用于实现这项任务的函数。
  • 但是ios_base类提供了setf函数,能够多种格式化特性
  • 如显示末尾小数点:cout.setf(ios_base::showpoint);
  • 使用默认的精度时,上述可以将2,显示2.000000(精度为6)
  • 改变精度为2时,显示2.
  • showpoint是ios_base类声明中定义的类级静态常量。类级意味着如果在成员函数定义的外面使用它,则必须在常量名前面加上作用域运算符(::),因此ios_base::showpoint指的事在ios_base类中定义的一个常量。

//===============================================================
//FileName:
//          showpt.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// showpt.cpp -- setting the precision, showing trailing point
#include <iostream>

int main()
{
	using std::cout;
	using std::ios_base;//ios_base类

//------------------------------------------------------------------------

	float price1 = 20.40;
	float price2 = 1.9 + 8.0 / 9.0;

//------------------------------------------------------------------------

	cout.setf(ios_base::showpoint);
	//使用默认的浮点精度时(6),将默认导致末尾的0被显示出来
	cout << "\"Furry Friends\" is $" << price1 << "!\n";
	cout << "\"Fiery Fiends\" is $" << price2 << "!\n";

//------------------------------------------------------------------------
	//改变精度时,末尾的0就不会显示
	cout.precision(2);
	cout << "\"Furry Friends\" is $" << price1 << "!\n";
	cout << "\"Fiery Fiends\" is $" << price2 << "!\n";
	// std::cin.get();
	return 0;
}

"Furry Friends" is $20.4000!
"Fiery Fiends" is $2.78889!
"Furry Friends" is $20.!
"Fiery Fiends" is $2.8!

setf()

单个参数
常量含义
ios_base::boolalpha输入和输出bool值,可以为true或false
ios_base::showpoint显示末尾的小数点
ios_base::showbase
ios_base::uppercase对于16进制输出,可以使用大写字母,E表示法
ios_base::showpos在正数前面加上+
  • 修改将一直有效,直到被覆盖为止

//===============================================================
//FileName:
//          setf.cpp
//Date:
//          2019/11/30
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================


// setf.cpp -- using setf() to control formatting
#include <iostream>

int main()
{
	using std::cout;
	using std::endl;
	using std::ios_base;

//------------------------------------------------------------------------

	int temperature = 63;

	cout << "Today's water temperature: ";
	cout.setf(ios_base::showpos);    // show plus sign
	cout << temperature << endl;

//------------------------------------------------------------------------

	cout << "For our programming friends, that's\n";
	cout << std::hex << temperature << endl; // use hex

//------------------------------------------------------------------------

	cout.setf(ios_base::uppercase);  // use uppercase in hex
	cout.setf(ios_base::showbase);   // use 0X prefix for hex
	cout << "or\n";
	cout << temperature << endl;
	cout << "How " << true << "!  oops -- How ";

//------------------------------------------------------------------------

	cout.setf(ios_base::boolalpha);
	cout << true << "!\n";


	return 0;
}

两个参数
  • 参数1:和以前一样,也是一个包含了所需设置的fmtflags值。
  • 参数2:指出要清楚第一个参数的那些位
  • 返回以前的设置
    例:ios_base::fmtflags old = cout.setf(ios::left,ios::adjustfield);
    由于setf函数时ios_base类的一个成员函数,由于这个类是ostream类的基类,所以可以使用cout对象来调用该函数。
    要恢复以前的设置:cout.setf(old,ios::adjustfield);

在这里插入图片描述
在这里插入图片描述


//===============================================================
//FileName:
//          setf2.cpp
//Date:
//          2019/12/2
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================


#include <iostream>




int main() {

	using namespace std;

	// use left justification, show the plus sign, show trailing
	cout.setf(ios_base::left, ios_base::adjustfield);

//------------------------------------------------------------------------

	// zeros, with a precision of 3
	cout.setf(ios_base::showpos);
	cout.setf(ios_base::showpoint);
	cout.precision(3);

//------------------------------------------------------------------------
	cout.precision(3);

//------------------------------------------------------------------------

	// use e-notation and save old format setting
	ios_base::fmtflags old = cout.setf(ios_base::scientific,ios_base::floatfield);

//------------------------------------------------------------------------

	cout << "Left Justification:\n";
	long n;

	for (n = 1; n <= 41; n += 10)
	{
		cout.width(4);
		cout << n << "|";
		cout.width(12);
		cout << sqrt(double(n)) << "|\n";
	}

//------------------------------------------------------------------------

	// change to internal justification
	cout.setf(ios_base::internal, ios_base::adjustfield);

//------------------------------------------------------------------------

	// restore default floating-point display style
	cout.setf(old, ios_base::floatfield);


//------------------------------------------------------------------------

	cout << "Internal Justification:\n";
	for (n = 1; n <= 41; n += 10)
	{
		cout.width(4);
		cout << n << "|";
		cout.width(12);
		cout << sqrt(double(n)) << "|\n";
	}

	// use right justification, fixed notation
	cout.setf(ios_base::right, ios_base::adjustfield);
	cout.setf(ios_base::fixed, ios_base::floatfield);

//------------------------------------------------------------------------

	cout << "Right Justification:\n";
	for (n = 1; n <= 41; n += 10)
	{
		cout.width(4);
		cout << n << "|";
		cout.width(12);
		cout << sqrt(double(n)) << "|\n";
	}
	return 0;



}
标准控制符

例如:打开左对齐和定点选项:
cout<<left<<fixed;
在这里插入图片描述
在这里插入图片描述

头文件iomanip
  • 在头文件应用iomanip
  • 表示和使用更方便
  • 3个常用的setprecision()setfill(), setw()
  • 3个带参数,只需把需要设置的值当做参数传入就行
  • 由于都是控制符,可以用cout语句连接起来。

//===============================================================
//FileName:
//          iomanip.cpp
//Date:
//          2019/12/2
//Author:
//          khoing(https://blog.youkuaiyun.com/qq_45391763)
//===============================================================

// iomanip.cpp -- using manipulators from iomanip
// some systems require explicitly linking the math library

#include <iostream>
#include <iomanip>


int main()
{
	using namespace std;
	// use new standard manipulators
	cout << fixed << right;

//------------------------------------------------------------------------

	// use iomanip manipulators
	cout << setw(6) << "N" << setw(14) << "square root"
		<< setw(15) << "fourth root\n";//这样设置只能有一次起作用

//------------------------------------------------------------------------

	double root;
	for (int n = 10; n <= 100; n += 10)
	{
		root = sqrt(double(n));
		cout << setw(6) << setfill('.') << n << setfill(' ')
			<< setw(12) << setprecision(3) << root
			<< setw(14) << setprecision(4) << sqrt(root)
			<< endl;
	}

//------------------------------------------------------------------------


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值