由浅入深C++语言中的输入输出流

1、输入输出流 cin 和 cout

C++中的输入输出都是通过流来进行的,而具体的输出输入都是通过对流进行操作来完成的。输入和输出并不是C++语言中的正式组成成分。C和C++本身都没有为输入和输出提供专门的语句结构。输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的。

C++的输出和输入是用“流”(stream)的方式实现的。下图表示C++通过流进行输入输出的过程。
这里写图片描述

有关流对象cin、cout和流运算符的定义等信息是存放在C++的输入输出流库中的,因此如果在程序中使用cin、cout和流运算符,就必须使用预处理命令把头文件iostream包含到本文件中,并使用命名空间std

    #include <iostream>
    using namespace std;

尽管cin和cout不是C++本身提供的语句,但是在不致混淆的情况下,为了叙述方便,常常把由cin和流提取运算符“>>”实现输入的语句称为输入语句或cin语句,把由cout和流插入运算符“<<”实现输出的语句称为输出语句或cout语句。根据C++的语法,凡是能实现某种操作而且最后以分号结束的都是语句。

2、输入流与输出流的基本操作

cout语句的一般格式为:

cout<<表达式1<<表达式2<<……<<表达式n;
  • 1

cin语句的一般格式为:

cin>>变量1>>变量2>>……>>变量n;

在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或’\n’,ends,flush)为止,此时将缓冲区中已有的数据一起输出,并清空缓冲区。输出流中的数据在系统默认的设备(一般为显示器)输出。

一个cout语句可以分写成若干行。如:

   cout<<"This is a simple C++ program."<<endl;
  • 1
可以写成:
   cout<<"This is "  //注意行末尾无分号
   <<"a C++ "
   <<"program."
   <<endl; //语句最后有分号

也可写成多个cout语句,即:

   cout<<"This is "; //语句末尾有分号
   cout <<"a C++ ";
   cout <<"program.";
   cout<<endl;

以上3种情况的输出均为:
This is a simple C++ program.

注意:不能用一个插入运算符“<<”插入多个输出项,如:

    cout<<a,b,c; //错误,不能一次插入多项
    cout<<a+b+c; //正确,这是一个表达式,作为一项
  • 1
  • 2

在用cout输出时,用户不必通知计算机按何种类型输出,系统会自动判别输出数据的类型,使输出的数据按相应的类型输出。如已定义a为int型,b为float型,c为char型,则:

    cout<<a<<' '<<b<<' '<<c<<endl;
  • 1

会以下面的形式输出:
4 345.789 a

与cout类似,一个cin语句可以分写成若干行。如:

    cin>>a>>b>>c>>d;
  • 1

可以写成:

   cin>>a //注意行末尾无分号
   >>b //这样写可能看起来清晰些
   >>c
   >>d;

也可以写成

   cin>>a;//末尾有分号
   cin>>b;
   cin>>c;
   cin>>d;

以上3种情况均可以从键盘输入: 1 2 3 4 ↙

也可以分多行输入数据:
1↙
2 3↙
4↙

在用cin输入时,系统也会根据变量的类型从输入流中提取相应长度的字节。如有:

   char c1,c2;
   int a;
   float b;
   cin>>c1>>c2>>a>>b;
  • 1

可以输入
1234 56.78↙

注意: 34后面至少应该有空格以便和56.78分隔开。也可以按下面格式输入:
1 2 34 56.78↙ (在1和2之间有空格)

不能用cin语句把空格字符和回车换行符作为字符输入给字符变量,它们将被跳过。想将空格字符或回车换行符(或任何其他键盘上的字符)输入给字符变量,需要使用其他函数,下面会介绍。
在组织输入流数据时,要仔细分析cin语句中变量的类型,按照相应的格式输入,否则容易出错。

3、几个容易混淆的重要函数

在刚刚进行C++的学习时,非常容易混淆下面的这些函数的作用:
1、cin
2、cin.get()
3、cin.getline()
4、getline()
5、gets()

本节就分别对上述的一系列函数进行详细的分析:

在这些函数中,当输入字符串时,都是以输入回车表示输入结束,程序自动在字符串结尾加上’\0’空字符表示字符串结束,除了cin.get()无参数或1个参数时可以吸收回车符之外,其他情况的应用不能接收回车符。当接收字符串时,如果没有输入内容,直接按下回车键,则字符串的第一个元素就是’\0’结束符。

注意:cin和cin.get()输入时,对结束时的回车不会吸收,’\n’还留在输入 缓冲区,因此在他们之后如果还要使用cin.get(),cin.getline(),getline()时,需要先加上cin.get()吸收上一次输入结束时的回车符。

但是在cin.getline(),getline()之后不需要进行吸收回车。
而且在下一行是cin时,不需要进行吸收回车,cin会忽略之前的空格和回车。

下面表示字符串的变量应当采用数组或string类型,不要采用char*指针类型。

1、cin

用法1:是最基本,也是最常用的用法,输入一个数字:

例1:

#include <iostream>
using namespace std;
int main ()
{
    int a,b;
    cin>>a>>b;
    cout<<a+b<<endl;
    return 0;
}

输入:2[回车]3[回车]
输出:5

例2:

#include <iostream>
using namespace std;

int main()
{
    int a, b;
    while(cin>>a>>b)
    {

        cout<<a+b
        <<endl;
    }

    return 0;
}

可以环输入数据,输入字母时程序退出。

用法2:接受一个字符串,遇“空格”、“TAB”、“回车”都结束。

#include <iostream>
using namespace std;
main ()
{
    char a[20];//此处也可以是char* a;
    cin>>a;
    cout<<a<<endl;
}

输入:jkljkljkl
输出:jkljkljkl
输入:jkljkl jkljkl //遇空格结束
输出:jkljkl

2、cin.get()函数
该函数可以接收空格、TAB和回车输入。

用法1: cin.get(字符变量名)
可以用来接收字符,可以接收空格、TAB和回车。

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

输入:jljkljkl
输出:j

用法2:cin.get(字符数组名,接收字符数目)
用来接收一行字符串,可以接收空格。

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

输入:jkl jkl jkl
输出:jkl jkl jkl
输入:abcdeabcdeabcdeabcdeabcde (输入25个字符)
输出:abcdeabcdeabcdeabcd (接收19个字符+1个’\0’)

用法3:cin.get(无参数) 吸收回车符
没有参数主要是用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,接收字符数目)的不足。

#include <iostream>
using namespace std;

int main() 
{ 
    int n;
    cin>>n;

    cin.get();    // 可以去掉这句对比以下效果

    char c;
    c = cin.get();

    cout<<n<<endl<<c<<endl;
    return 0; 
} 

如果没有吸收回车符,由于cin.get()可以接收回车符,c字符的cin.get()会把输入n结束时的回车符吸收作为c的内容,因此在下文紧接着有cin.get()函数时,需要先加上一个cin.get()来吸收上文输入结束时的回车符。

注意点:cin.get()吸收的回车符会表示为换行符

cout << "。。。请按回车键。。。" << endl;

char c;
c=getch();
cout << "按回车键后,得到的ascii码是: " << int(c) << endl;//码值为13,回车符'\r'

cout << "。。。请按回车键。。。" << endl;

char ch;
cin.get(ch);
cout << "按回车键后,得到的ascii码是: " << int(ch) << endl;//码值为10,换行符'\n'

需要注意的是:cin.get(ch);输入回车,得到的ch为换行符’\n’,使用ch=getch();函数可以得到回车符’\r’。getch()为C语言中的函数。

3、cin.getline()函数
接受一个字符串,可以接收空格并输出。

用法1:接收字符串
该用法与cin.get()的接收字符串用法相同

#include <iostream>
using namespace std;
main ()
{
    char m[20];
    cin.getline(m,5);
    cout<<m<<endl;
}

输入:jkljkljkl
输出:jklj
接受5个字符到m中,其中最后一个为’\0’,所以只看到4个字符输出。

用法2:cin.getline()实际上有三个参数
cin.getline(接受字符串的数组m,接受个数5,结束字符)
当第三个参数省略时,系统默认为’\0’。
如果将上面的例子中cin.getline()改为cin.getline(m,5,’a’);当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk。

再举一例:使用多维数组

#include <iostream>
using namespace std;

int main()
{
    char a[3][20];

    cout<<"请输入第一个字符串"<<endl;
    cin.getline(a[0], 20);
    cout<<"请输入第二个字符串"<<endl;
    cin.getline(a[1], 20);  
    cout<<"请输入第三个字符串"<<endl;
    cin.getline(a[2], 20);  

    cout<<a[0]<<endl; 
    cout<<a[1]<<endl;   
    cout<<a[2]<<endl; 

    return 0;   
}

4、getline()函数
接受一个字符串,可以接收空格并输出
需包含#include <string>
格式:getline(cin, str); //str必须是string类型

用法举例:

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

int main()
{
    string a;//注意是string类型

    cout<<"请输入一个字符串"<<endl;
    getline(cin, a);//注意函数的参数

    cout<<a<<endl; 

    return 0;   
}

和cin.getline()的作用类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数。

5、gets() 函数
接受一个字符串,可以接收空格并输出。
需包含#include<string>

#include<iostream>
#include<string>
using namespace std;
int main ()
{
    char m[20];
    gets(m);    //不能写成m=gets();
    cout<<m<<endl;
    return 0;
}

输入:jkljkljkl
输出:jkljkljkl
输入:jkl jkl jkl
输出:jkl jkl jkl

4、在输入流与输出流中使用控制符

需要注意的是:如果使用了控制符,在程序单位的开头除了要加iostream头文件外,还要加iomanip头文件。

#include <iostream>
#include <iomanip>
using namespace std;
  • 1
  • 2

举例: 输出双精度数。
double a=123.456789012345; 对a赋初值
(1)cout<<a; 输出: 123.456
(2)cout<<setprecision(9)<<a; 输出: 123.456789
(3)cout<<setprecision(6); 恢复默认格式(精度为6)
(4)cout<<setiosflags(iOS∷fixed); 输出: 123.456789,以带小数点的形式表示浮点数
(5)cout<<setiosflags(ios∷fixed)<<setprecision(8)<<a; 输出: 123.45678901
(6)cout<<setiosflags(ios∷scientific)<<a; 输出: 1.234568e+02
(7)cout<<setiosflags(ios∷scientific)<<setprecision(4)<<a; 输出: 1.2346e02

下面是整数输出的例子:
int b=123456;对b赋初值
(1)cout<<b;输出: 123456
(2)cout<<hex<<b; 输出: 1e240
(3)cout<<setiosflags(ios∷uppercase)<<b;输出: 1E240
(4)cout<<setw(10)<<b<<','<<b; 输出: 123456,123456
(5)cout<<setfill('*')<<setw(10)<<b;输出: * * * * 123456
(6)cout<<setiosflags(ios∷showpos)<<b;输出: +123456

如果在多个cout语句中使用相同的setw(n),并使用setiosflags(ios∷right),可以实现各行数据右对齐,如果指定相同的精度,可以实现上下小数点对齐。

例:各行小数点对齐。

#include <iostream>
#include <iomanip>
using namespace std;
int main( )
{
   double a=123.456,b=3.14159,c=-3214.67;
   cout<<setiosflags(ios∷fixed)<<setiosflags(ios∷right)<<setprecision(2);
   cout<<setw(10)<<a<<endl;
   cout<<setw(10)<<b<<endl;
   cout<<setw(10)<<c<<endl;
   return 0;
}

输出如下:
这里写图片描述
先统一设置小数形式输出、取两位小数、右对齐。这些设置对其后的输出均有效(除非重新设置),而setw只对其后一个输出项有效,因此必须在输出a,b,c之前都要写setw(10)。

需要注意的是setw(int n)表示的是后面的输出内容所占的位置的数目为n,根据设定来右对齐还是左对齐,如果后面的输出内容没有达到所设定的n个空间,则默认有空格来填充,也可由cout<<setfill('*')<<setw(10)<<b;来指定星号来填充。整个b变量显示的内容加上空格或星号总共有10个空间。

posted @ 2017-05-18 15:38  tsvico  阅读(312)  评论(0编辑  收藏  举报