C++入门很轻松(微课超值版)
上QQ阅读APP看书,第一时间看更新

2.4 数据的输入与输出

微视频

在用户与计算机进行交互的过程中,数据的输入与输出是不可或缺的。计算机通过输入数据来获取用户的操作指令,并通过输出数据来显示操作结果。

2.4.1 认识控制台

在Windows操作系统中,保留了DOS系统的风格,并提供了控制台,也就是我们常用的“命令提示符”窗口。用户可以通过选择“开始”→“运行”命令,打开“运行”对话框,如图2-13所示,然后在“打开”文本框中输入cmd.exe命令并按Enter键,从而打开“命令提示符”窗口,如图2-14所示。

图2-13 “运行”对话框

图2-14 “命令提示符”窗口

在控制台中可以运行dir、cd、delete等DOS系统中的文件操作命令,也可以用来启动Windows程序。使用VC++ 6.0创建的控制台工程程序都将运算结果输出到这个控制台上,它是程序显示输出结果的地方。

☆大牛提醒☆

本书中使用的Visual Studio 2019编译软件自带调试控制台。当程序运行后,结果会显示在如图2-15所示的调试控制台中。

图2-15 调试控制台

2.4.2 C++语言中的流

在C++语言中,数据的输入与输出包括标准输入/输出设备(键盘、显示器)、外部存储介质上的文件(磁盘或U盘中的文件)和内存的存储空间3个方面的输入/输出。对标准输入设备和标准输出设备的输入/输出简称为标准I/O,对在外存磁盘上文件的输入/输出简称文件I/O,对内存中指定的字符串存储空间的输入/输出简称为串I/O。

C++语言中把数据之间的传输操作称为“流”。所谓的“流”,是从数据的传输抽象而来的,可以将其理解为文件。C++中的流既可以表示数据从内存传送到某个载体或设备中(即输出流),也可以表示数据从某个载体或设备传送到内存缓冲区变量中(即输入流)。

C++语言定义了I/O流库供用户使用,常用的标准I/O操作包括cin和cout。其中,cin代表标准输入设备键盘,也称为cin流或标准输入流;cout代表标准输出显示器,也称为cout流或标准输出流。当通过键盘输入操作时使用cin流,当进行显示器输出操作时使用cout流。如图2-16表示C++通过流进行数据输入/输出的过程。

图2-16 C++通过流进行输入/输出的过程

有关cin、cout和流运算符(<<和>>)的定义是预先定义好的流对象,存放在C++的输入/输出流库中。因此,如果在程序中使用cin、cout和流运算符,就必须使用预处理命令把头文件iostream包含到程序中,语句如下:

    #include <iostream>

C++的流通过重载运算符“>>”和“<<”执行输入和输出操作。输出操作是向流中插入一个字符序列,因此将左移运算符“<<”称为插入运算符。输入操作是从流中提取一个字符序列,因此将右移运算符“>>”称为提取运算符。

2.4.3 认识cout与cin语句

1.cout语句的一般格式

cout语句的一般格式如下:

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

cout代表显示器,执行“cout<<表达式1”操作就是相当于把表达式1的值输出到显示器。cout可以输出整数、实数、字符及字符串,cout中插入符“<<”后面可以跟变量、常量、转义字符、对象等表达式。在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入/输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或'\n'、ends、flush)为止,此时将缓冲区中已有的数据一起输出并清空缓冲区。

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

    cout<<"This is a C++ program."<<endl;

可以写成

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

也可以写成

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

以上3种情况的输出结果均为:

    This is a C++ program.

【实例2.8】编写程序,在屏幕上输出数字和字符串(源代码\ch02\2.8.txt)。

    #include <iostream>
    using namespace std;
    int main()
    {
         int a=10;                       //定义int型变量a,并赋值为10
         cout <<a<<endl;                 //输出变量a的值,并换行
         cout << "Hello World!" <<endl;  //输出"Hello World!",并输出一个换行
    }

程序运行结果如图2-17所示,即向屏幕输出变量a的值和'Hello World!'字符串。在代码中,endl是向流的末尾部位加入换行符;a是一个整型变量,在输出流中会自动将整型变量转换成字符串输出。

图2-17 例2.8的程序运行结果

2.cin语句的一般格式

cin语句的一般格式如下:

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

cin代表键盘,执行“cin>>变量1”操作就是相当于把键盘输入的数据赋予变量1。当从键盘上输入数据时,只有当输入完数据并按Enter键后,系统才把该行数据存入到键盘缓冲区,以供cin流将其按顺序读取给变量。另外,从键盘上输入的每个数据之间必须用空格或回车符分开,因为cin为一个变量读入数据是以空格或回车键作为其结束标志的。

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

    cin>>a>>b>>c>>d;

可以写成

    cin>>a  //注意行末尾无分号
    >>b
    >>c
    >>d;

也可以写成

    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

以上3种情况均可以通过从键盘输入1234↙来实现,也可以像下面这样分多行输入数据。

    1↙
    23↙
    4↙

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

【实例2.9】编写程序,输出用户输入的数字和字符串(源代码\ch02\2.9.txt)。

    #include <iostream>
    using namespace std;
    int main()
    {
         cout << "请输入您的名字和年龄:" << endl;
         char name[10];
         int age;
         cin >> name;
         cin >> age;
         cout << "您的名字是:" << name << endl;
         cout << "您的年龄是:" << age << endl;
    }

程序运行结果如图2-18所示。在本例中,首先定义了一个char类型的数组name,又定义了一个int型的变量age,再使用cin从键盘输入name和age的值,最后将赋值的变量输出。从运行结果来看,利用cin实现了name和age的输入。

图2-18 例2.9的程序运行结果

2.4.4 流输出格式的控制

1.cout控制符的格式

使用cout输出数据时,一般采用默认格式,如整型按十进制形式输出,但在实际应用中,会输出一些具有特殊要求的数据,例如输出浮点数时规定字段宽度、只保留两位小数、数据向左或向右对齐等。为此,C++语言在头文件iomanip中定义了一些控制流输出格式的函数。表2-6所示为流控制的具体函数。

表2-6 流控制的具体函数

除了使用函数控制cout输出的格式外,数据输入/输出的格式控制还有更简洁的形式,就是使用头文件iomanip中提供的操作符。使用这些操作符不需要调用成员函数,只要把它们作为插入操作符(" ")的输出对象即可。表2-7所示为iomanip中提供的操作符。

表2-7 iomanip中提供的操作符

【实例2.10】编写程序,使用cout格式化输出结果(源代码\ch02\2.10.txt)。

    #include <iostream>
    #include <iomanip>
    using namespace std;
    int main()
    {
         double a=123.456789012345;         //对a赋初值
         cout<<a<<endl;                     //输出:123.456
         cout<<setprecision(9)<<a<<endl;    //输出:123.456789
         cout<<setprecision(6)<< a <<endl;  //恢复默认格式
         cout<<setiosflags(ios::fixed)<< a <<endl;                       //输出:123.456789
         cout<<setiosflags(ios::fixed)<<setprecision(8)<<a<<endl; //输出:123.45678901
         cout<<setiosflags(ios::scientific)<<a<<endl;                    //输出:0X1.edd3c080p+6
         cout<<setiosflags(ios::scientific)<<setprecision(4)<<a<<endl; //输出: 0X1.edd4p+6
         int b=123456;                                                   //对b赋初值
         cout<<b<<endl;                                                  //输出:123456
         cout<<hex<<b<<endl;                                             //输出:1e240
         cout<<setiosflags(ios::uppercase)<<b<<endl;                     //输出:1E240
         cout<<setw(10)<<b<<','<<b<<endl;                                //输出:1E240,1E240
         cout<<setfill('*')<<setw(10)<<b<<endl;                          //输出:****1E240
         cout<<setiosflags(ios::showpos)<<b<<endl;                       //输出:1E240
    }

程序运行结果如图2-19所示。在本例中,首先定义了一个double型变量a,再调用cout格式控制符,按照需要将double型变量a输出,然后又定义了int型变量b,再调用cout格式控制符将int型变量b输出。从运行结果来看,利用cout格式控制符,实现了各类数据的格式化输出。

图2-19 例2.10的程序运行结果

2.格式输出函数printf()

格式输出函数printf()主要是将标准输入流读入的数据向输出设备进行输出。一般形式如下:

    printf("格式字符串");
    printf("格式字符串",输出项列表);

(1)“格式字符串”用来指定输出的格式,由“普通字符”和“格式控制字符”组成。“普通字符”是指除了格式说明符外的需要原样输出的字符,一般是输出时的提示性信息,也可以输出空格及转义字符;“格式控制字符”由“%”和格式说明符组成,如%c、%d、%f等,用于将输出项依次转换为指定的格式输出。

例如,若已经定义了基本整型变量a并赋值为10,则可以像下面这样输出a的值。

    int a=10;
    printf("变量a的值为:%d\n", a);

输出的结果如下:

    变量a的值为:10

(2)“输出项列表”是需要输出的若干数据的列表,各项间由逗号隔开。每一项既可以是常量、变量,也可以是表达式。

例如,若已经定义了基本整型变量a、b,并且将a赋值为10、将b赋值为a+5,则可以像下面这样输出a和b的值。

    int a=10,b;
    printf("a=%d  b=%d\n", a, a+5);

输出的结果如下:

    a=10  b=15

C++语言中的printf()函数格式字符及说明如表2-8所示。

表2-8 printf()函数格式字符及说明

(1)d格式符。以十进制形式输出整数(正数不输出符号),具体用法如下。

● %d:指定按照实际占用的宽度输出十进制整型数据。

● %*md:m为指定的输出字段的宽度,如果数据的位数小于m,用*所指定的字符占位,否则*未指定用空格占位;如果大于m,则按实际位数输出。

● %ld:l为修饰符,用来指定长整型数据的输出格式。

(2)o格式符。以八进制形式输出整数(不输出前缀o),具体用法如下。

● %o:指定按照实际占用的宽度输出八进制整型数据。

● %*mo:m为指定的输出字段的宽度,如果数据的位数小于m,用*所指定的字符占位,否则*未指定用空格占位;如果大于m,则按实际位数输出。

● %lo:l为修饰符,用来指定长整型数据的输出格式。

(3)x格式符。以十六进制形式输出无符号整数(不输出前缀ox),具体用法如下。

● %x:指定按照实际占用的宽度输出十六进制整型数据。

● %*mx:m为指定的输出字段的宽度,如果数据的位数小于m,用*所指定的字符占位,否则*未指定用空格占位;如果大于m,则按实际位数输出。

● %lx:l为修饰符,用来指定长整型数据的输出格式。

(4)f格式符。以十进制小数形式输入/输出实数,包括单精度和双精度,具体用法如下。

● %f:不指定字段宽度,整数部分全部输出,小数部分输出6位。

● %m.nf:m和n都是正整数,输出的数据占m列,其中有n位小数。如果数值长度小于m,则左端补空格。

● %-m.nf:m和n都是正整数,输出的数据占m列,其中有n位小数。如果数值长度小于m,则右端补空格。

● %lf:l为修饰符,表示输出双精度数据。

(5)e格式符。以指数形式输出单精度、双精度实数,具体用法如下。

● %e:不指定字段宽度,整数部分全部输出,小数部分输出6位。

● %m.ne:m和n都是正整数,输出的数据占m位,其中有n位小数。如果数值长度小于m,则左端补空格。

● %-m.ne:m和n都是正整数,输出的数据占m位,其中有n位小数。如果数值长度小于m,则右端补空格。

(6)s格式符。输出一个字符串,具体用法如下。

● %s:将字符串按实际长度输出。

● %*ms:输出的字符串占m列,如果字符串本身大于m,则突破m的限制,用*所指定的字符占位,否则*未指定用空格占位;如果字符串长度小于m,则左补空格。

● %-ms:如果字符串长度小于m,则在m列范围内字符串向左靠,右补空格。

● %m.ns:m和n都是正整数,输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。

● %-m.ns:m和n都是正整数,输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的左侧,右补空格。

【实例2.11】编写程序,定义int型变量a、char型变量b、float型变量c,并为a、b、c分别赋值,最后通过输出函数printf()输出变量a、b、c的值(源代码\ch02\2.11.txt)。

    #include <iostream>
    #include <iomanip>
    using namespace std;
    int main()
    {
         int a=10;
         char b='A';
         float c=3.1415;
         printf("a=%d  b=%c  c=%f\n",a,b,c); /*在屏幕中输出a,b,c的值*/
    }

程序运行结果如图2-20所示。

图2-20 例2.11的程序运行结果