C++语言之输入输出深入介绍

本文包括:C++基本的输入输出、C++如何输入含空格的字符串、C++输入输出的格式控制。

本文介绍的内容适用于控制台程序,这样才能看到输入与输出的结果,GUI(图形用户界面)的程序就用不上了。

C++基本的输入输出

cin和cout

在C语言中,标准的键盘输入和屏幕输出功能分别使用scanf()和printf()两个函数实现。在C++语言中,类库中提供了输入流类istream和输出流类ostream。cin和cout分别是istream类和ostream类的对象,用来实现基本的键盘输入和屏幕输出。 引入头文件iostream后,就可以使用cin和cout。

cin和cout是 C++ 的内置对象(预定义的流类对象),cin用来处理标准输入,即键盘输入,因此也称cin是标准输入流对象。cout用来处理标准输出即屏幕输出,因此也称cout是标准输出流对象。

<<和>>

从输入流中获取数据的操作称为提取操作,向输出流中添加数据的操作称为插入操作。运算符“>>”和“<<”是移位运算符,但在C++类库中的头文件中已经对“>>”和“<<”进行了重载,使之分别作为流提取运算符和流插入运算符,用来输入和输出C++标准类型的数据。。例如,语句“cin>>x;”从键盘获取输入数据并赋给变量x。使用cin可以获得多个来自键盘的输入值。cout是一个标准输出流对象,使用流插入运算符“<<”向输出设备屏幕输出信息。当程序中用到cin和cout时,需要在程序中包含头文件。

cin的一般格式如下:

cin>> <变量名1>[>> <变量名2> >>…>> <变量名n>];

程序执行到这条语句便暂停下来,等待从键盘上输入相应数据,直到所列出的所有变量均获得值后,程序方继续执行。

cout的一般格式如下:

cout<< <表达式1> [<< <表达式2> <<…<< <表达式n>];

程序执行到这条语句时,将紧跟其后的表达式的值输出到显示器上。

注意,使用cin和cout必须在程序开头增加一行:

# include <iostream.h>

或者两行:

# include <iostream>

using namespace std;

【c++中的#include和using指令(directive)的作用

#include用于包含其他文件的内容,如用来引入对应的头文件。

using namespace std;这个using声明是将std命名空间内的名字,全部暴露在外,只要访问std命名空间内的名字,我们都不需要在cin、cout之前写额外的前缀std::。

更多情况,可参见https://blog.51cto.com/u_15314328/4965070】

下面给出一个例子,贺卡

#include<iostream>
using namespace std;
int main(void)
{
    string friendName;
    string selfName;
    cout<<"请输入朋友的名字:";
    cin>>friendName;
    cout<<"请输入你的名字:";
    cin>>selfName;    
    cout<<"===================================="<<endl;
    cout<<"My dear "<<friendName<<endl;
	cout<<"    Happy birthday to you!"<<endl;
	cout<<"        yours, "<<selfName<<endl;
    cout<<"===================================="<<endl;
    return 0;
}

用Dev-C++编译运行之:

C++如何输入含空格的字符串

cin是C++中最常用的输入,用空格或者回车键分隔数据。如用cin>>str;这种方法来接收字符串那么录入的str不能包含空格,否则它会按照空格将整个字符串切分成若干段。

cin>>a;

cout<<a<<endl; //例如输入“h kj s”,则在a中只有‘h’。

如何输入含有空格字符串呢?

可以使用get()、getline()函数

头文件 <istream> 中get()函数

get 函数是内置在 cin 对象中的,所以可称之为 cin 的一个成员函数。下面仅介绍两种用法,详情可见istream::get - C++ Reference

用法1: cin.get(字符变量名)

可以用来接收字符,示例源码:

#include <iostream>
using namespace std;
main ()
{
  char ch;
  cout<<"请输入:";
  ch=cin.get();               //或者cin.get(ch);
  cout<<ch<<endl;
}

用Dev-C++编译运行之:

用法2:cin.get(字符数组名,接收字符数目)

用来接收一行字符串,可以接收空格,示例源码:

#include <iostream>
using namespace std;
main ()
{
char a[20];
cout<<"请输入:";
cin.get(a,20);
cout<<a<<endl;
}

用Dev-C++编译运行之:

在C++中有两种getline()函数,一种在头文件 <istream> 中,是istream类的成员函数;另一种是在头文件 <string> 中,是普通函数。

头文件 <istream> 中的getline()函数

cin.getline 允许读取包含空格的字符串,其语法为:

getline (char* s, streamsize n [, char delim] );

参见istream::getline - C++ Reference

s:它是指向字符串以存储字符的指针。

n:它表示由a指向的最大字符数。

delim:这是一个明确的定界字符,默认是 '\n '。

返回值

读取n-1个字符(第n个用于保存'/0'),或者遇到指定的定界字符为止。

可用来接收一行含有空格的字符串,示例源码:

#include <iostream>
using namespace std;
main ()
{
char m[20];
cout<<"请输入:";
cin.getline(m,7);
cout<<m<<endl;
}

用Dev-C++编译运行之:

头文件<string>中的getline()函数

string版本的getline()函数有自动调整大小的功能,不需要指定读取多少个字符的数值参数,其语法为:

getline (istream& is, string& str [, char delim]);

参见getline (string) - C++ Reference

参数

is:表示一个输入流,例如 cin。

str:用来存储输入流中的信息

delim:定界字符,默认是 '\n '

可用来接收一行含有空格的字符串,示例源码:

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string s;
  cout<<"请输入:";
  getline(cin,s);
  cout << s << endl;

  return 0;
}

用Dev-C++编译运行之:

关于C++中getline()的更多情况,可见 https://www.jb51.net/article/180289.htm

C++输入输出的格式控制

在没有特地进行格式控制的情况下,输入输出采用默认格式,先看一下这种情况是什么样的。

默认的输入格式

C++流所识别的输入数据的类型及其默认的输入格式:

 short、int 、long(signed 、unsigned):与整型常量同;

 float、double、long double:与浮点数常量同;

 char(signed、unsigned):第一个非空白字符;

 char *(signed 、unsigned):从第一个非空白字符开始到下一个空白字符结束;

 void *:无前缀的16进制数;

 bool:把true或1识别为true,其他的均识别为false(VC6.0中把0识别为false,其他的值均识别为true)。

示例源码

#include <iostream>
using namespace std;
main ()
{
  int a,b; char c; char d[30];
  cout<<"请输入值:";
  cin>>a>>b>>c>>d; 
  
  cout<<"a="<<a<<"   b="<<b<<"   c="<<c<<"   d="<<d<<endl;
  return 0; 
}

用Dev-C++编译运行之:

请分析一下,为何请输入:123  456abcdefgh  ijklm

输出a=123   b=456   c=a   d=bcdefgh

默认的输出格式

C++流所识别的输出数据的类型及其默认的输出格式:

  char(signed、unsigned):单个字符(无引号);

  short、int、long(signed  、unsigned):一般整型形式,负数前有-号;

  char *(signed  、unsigned):字符序列(无引号);

  float  、double  、long double:浮点格式或指数格式(科学表示法),取决于哪个更短;

  void *:无前缀的16进制数;

  bool:1或0。

示例源码

#include <iostream>
using namespace std;
main ()
{
  char c='A';
  const char *p="hello!";
  cout<<123<<c<<-123<<endl;
  cout<<p<<(void *)p<<endl;
  cout<<true;
  return 0; 
}

用Dev-C++编译运行之:

进行输入输出的格式控制,可以使用iostream库,需要加入头文件#include<iostream>使用,还可以iomanip库,进行输入输出的格式控制,iomanip 是 IO manipulators 的缩写,需要加入头文件#include<iomanip>。

iostream库

在C++中,iostream头文件,iostream 是 Input Output Stream 的缩写,意思是“输入输出流”,提供了 cin对象(一般情况下代表显示器) 和 cout对象(一般情况下代表显示器),分别用于从标准输入读取流 和 向标准输出写入流。

cin 就是 istream 类的对象,cout 是 ostream 类的对象,它们都声明在 <iostream> 头文件中,这也解释了“为什么在 C++ 程序中引入 <iostream> 就可以使用 cin 和 cout”。

iostream库的每个iostream对象还维护着一个格式状态来控制IO格式化细节。

关于iostream库详情可见如下链接

https://cplusplus.com/reference/iostream/

https://www.apiref.com/cpp-zh/cpp/header/iostream.html

https://blog.csdn.net/m0_60073820/article/details/121319269

iostream库定义了一组操纵符来修改流的格式状态。操纵符是一个函数或对象,会影响流的状态,并能作为输入和输出运算符的运算对象。

操纵符用于两大类输出控制:控制数值的输出格式,控制补白的数量和位置。大多数改变格式状态的操纵符都是设置/复原成对的,一个操纵符用于设置新格式,另一个用于恢复正常格式。

当操纵符改变流的格式状态时,通常改变后的状态对所有后续IO都生效。

bool值默认打印0或1,可以对流使用boolalpha来操纵覆盖这种格式,示例源码:

#include <iostream>
using namespace std;
main ()
{
    cout << "default bool values: " << true << " " << false<< endl;
    cout << boolalpha;
	cout << "boolalpha bool values: " <<true << " " << false << endl;
	cout << noboolalpha; //取消改变用noboolalpha:
	cout << "noboolalpha  bool values: " <<true << " " << false << endl;
    return 0; 
}

用Dev-C++编译运行之:

默认输出十进制,可以用hex、oct和dec改为十六进制、八进制和十进制。只影响整型。

示例源码:

#include <iostream>
using namespace std;
main ()
{
    cout << "default: " << 20 << " " << 1024 << endl;
    cout << "octal: " << oct << 20 << " " << 1024 << endl;
    cout << "hex: " << hex << 20 << " " << 1024 << endl;
    cout << "decimal: " << dec << 20 << " " << 1024 << endl;
    return 0; 
}

用Dev-C++编译运行之:

控制浮点数格式

浮点数的输出格式涉及三个方面:

输出精度(即输出多少个数字)。

十六进制、定点十进制或者科学记数法形式输出。

没有小数部分的浮点值是否输出小数点。

默认情况下,浮点值按六位数字精度输出;如果浮点值没有小数部分,则不输出小数点;根据浮点数的值选择输出为定点十进制或科学计数法形式:非常大或非常小的值输出为科学记数法形式,其他值输出为定点十进制形式。

默认情况下,精度控制输出的数字总位数。输出时,浮点值按照当前精度四舍五入而非截断。

调用IO对象的precision成员或者使用setprecision操纵符可以改变精度。

示例源码:

#include <iostream>
#include <math.h>
using namespace std;
main ()
{
    // cout.precision返回当前精度值
    cout << "Precision: " << cout.precision() << ", Value: " << sqrt(2.0) << endl;
    // cout.precision(12)将打印精度设置为12位数字
    cout.precision(12);
    cout << "Precision: " << cout.precision() << ", Value: " << sqrt(2.0) << endl;
    return 0; 
}

用Dev-C++编译运行之:

c++设置域宽

用于存放输出数据的宽度称为“域宽”。浮点数的域宽包含小数点。

如果所需的宽度比设置的域宽小,空位用填充字符填充。如果显示数据所需的宽度比设置的域宽大,系统输出所有位。域宽设置仅对下一行流读入或流插入操作有效,在一次操作完后被置0。

指定输入域宽示例源码:

#include <iostream>
using namespace std;
main ()
{
    char str[20],str2[20];
    cout << "请输入一段文本: ";
    cin.width(5);
	cin>>str;	//cin>>str;实际只能提取4个字符,str最后一个是空字符,其他的放在流中等待接受。 
	cout<<str<<endl;
	cin>>str2;
    cout<<str2<<endl;
    return 0; 
}

用Dev-C++编译运行之:

指定输出域宽示例源码:

#include <iostream>
using namespace std;
main ()
{
    cout<<"abc123"<<endl;
    cout.width(10); 
	cout<<"abc123"<<endl;
	cout<<1.2345<<endl;
    cout.width(10); 
	cout<<1.2345<<endl;
   
    return 0; 
}

用Dev-C++编译运行之:

cin与cout都可以指定域宽。上面的例子是用iostream库的cin.width函数成员指定输入域宽,cout.width函数成员指定输出域宽。

也可以iomanip库setw指定输入和输出域宽。

用iomanip库的setw函数指定输入和输出域宽需要加入头文件#include<iomanip>,源码如下:

#include <iostream>
#include <iomanip>
using namespace std;
main ()
{
    char d[10];
    cout<<"Please enter a text:";
    cin>>setw(5);
    cin>>d; 
    cout <<setw(8);
    cout<<d<<endl;
  return 0; 
}

用Dev-C++编译运行之:

常见控制符汇总表:

         控   制   符                    

        作           用                                     

 dec 

 设置整数为十进制

 hex

 设置整数为十六进制

 oct

 设置整数为八进制

 setbase(n)

 设置整数为n进制(n=8,10,16)

 setfill(n)

 设置字符填充,c可以是字符常或字符变量

 setprecision(n)

 设置浮点数的有效数字为n位

 setw(n)

 设置字段宽度为n位

 setiosflags(ios::fixed)

 设置浮点数以固定的小数位数显示

 setiosflags(ios::scientific)  

 设置浮点数以科学计数法表示

 setiosflags(ios::left)

 输出左对齐

 setiosflags(ios::right)

 输出右对齐

 setiosflags(ios::skipws)

 忽略前导空格

 setiosflags(ios::uppercase)

 在以科学计数法输出E与十六进制输出X以大写输出,否则小写。

 setiosflags(ios::showpos)

 输出正数时显示"+"号

 setiosflags(ios::showpoint)

 强制显示小数点

 resetiosflags() 

 终止已经设置的输出格式状态,在括号中应指定内容

下面给出示例

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    // 前缀0表示八进制 前缀0x表示十六进制 不带前缀表示十进制
    int a = 123;
    double pi = 22.0/7.0;

    // setbase(n) 设置整数为n进制(n=8,10,16)
    // oct 八进制 dec 十进制 hex 十六进制
    // setiosflags(ios::showbase) 显示进制的前缀
    // 数值默认十进制显示输出
    cout << a << endl;
    cout << "oct: " << showbase << setbase(8) << a << " " << oct << a << endl;
    cout << "dec: " << showbase << setbase(10) << a << " " << dec << a << endl;
    cout << "hex: " << showbase << setbase(16) << a << " " << hex << a << endl;

    // setprecision(n) 设置浮点数的有效数字为n位
    // 有效位数默认是6位,即setprecision(6),即小数点前面和小数点后面加起来的位数为6个有效数字(注意会四舍五入)
    cout << pi << endl;
    cout << setprecision(12) << pi << endl;

    // setfill(n) 设置字符填充,c可以是字符常或字符变量
    // setw(n) 设置字段宽度为n位, 若是实际宽度大于被设置的,则setw函数此时失效, 只针对其后的第一个输出项有效
    // setiosflags(ios::left) 输出左对齐
    // setiosflags(ios::right) 输出右对齐 默认右对齐
    cout << setfill('*') << setw(20) << setprecision(12) << pi << endl;
    cout << setfill('*') << setw(20) << setprecision(12) << right << pi << endl;
    cout << setfill('*') << setw(20) << setprecision(12) << left << pi << endl;

    // setiosflags(ios::fixed) 设置浮点数以固定的小数位数显示
    cout << fixed << setprecision(12) << pi << endl;

    // setiosflags(ios::scientific)  设置浮点数以科学计数法表示 科学计数法输出E与十六进制输出默认是以小写的,要换成大写需添加uppercase
    cout << scientific << setprecision(12) << pi << endl;
    cout << scientific << uppercase << setprecision(12) << pi << endl;

    // resetiosflags() 终止已经设置的输出格式状态,在括号中应指定内容
    cout << setiosflags(ios::scientific) << setprecision(12) << pi << "   " << resetiosflags(ios::scientific) << pi << endl;

    return 0;
}

用Dev-C++编译运行之:

补充总结 可参见“C++中数据的输入输出总结” https://blog.csdn.net/cnds123/article/details/132045856

附录、C++学习资源
C++ [中文] https://runebook.dev/zh-CN/docs/cpp/-index-

C++ 参考手册 https://www.apiref.com/cpp-zh/cpp.html
https://cplusplus.com/reference/

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐