备战蓝桥杯,第二章:C++语言的输入输出(上)

一.getchar和putchar

getchar和putchar是属于C语言的库函数,C++语言是兼容C语言的知识的,所以C++只要正确包含头文件就可以使用这两个函数,

1.getchar函数

函数原型如下:

cpp 复制代码
int getchar ( void );

该函数返回用户从键盘输入的一个字符,使用时不带有任何参数。程序运行到这个命令就会暂停,等待用户从键盘输入,等同于cin和scanf函数,它的原型定义在头文件<cstdio>中。

cpp 复制代码
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
 int ch;
 ch = getchar();
 cout << ch << endl;
 cout << (char)ch << endl;
 return 0;
}

上述代码的具体解释:上述代码会读取用户键盘输入的字符,并且利用强制类型转化将其字符打印在屏幕上。

该函数不会忽略空白字符,总是返回当前读取的第一个字符,无论是否为空格。如果读取失败,返回常量EOF(整型常量-1),因此该函数的返回值类型为整型int类型,而不是char类型。

如何让该函数读取失败,返回-1呢?

答:需要在输入字符之前,点击Ctrl+z即可。

cpp 复制代码
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
 int ch;
 ch = getchar();
 cout << ch << endl;
 return 0;
}

知道了读取字符的函数,那么在打印时总不能一直强制类型转换吧!所以就有了打印字符的函数putchar,接下来让我们一起学习一下吧!

2.putchar函数

函数原型如下:

cpp 复制代码
int putchar( int character );

该函数将参数字符输出到屏幕上,它的原型也定义在<cstdio>文件中。

cpp 复制代码
#include <cstdio>
int main()
{
 int ch = 0;
 ch = getchar();
 putchar(ch);
 
 return 0;
}

操作成功时,该函数返回输出的字符,否则将返回常量EOF。

二.scanf和printf

scanf和printf两个函数属于C语言的库函数,因为C++语言是兼容C语言的语法结构的。所以只要正确包含头文件,就可以正常使用。

1.printf函数

该函数的原型如下:

cpp 复制代码
int printf ( const char * format, ... );

(1)基本用法

该函数的作用是将参数文本输出到屏幕上,函数名中的f代表的是format格式化的意思。表示可以定制输出文本的格式。

cpp 复制代码
#include <cstdio>
int main() 
{
 printf("Hello World");
 return 0;
}

上述代码会在屏幕上输出双引号内部的字符串。该函数不会默认输出后换行,要想换行必须在输出文本的末尾加上换行符\n。如下代码所示:

cpp 复制代码
#include <cstdio>
int main() 
{
 printf("Hello World\n");
 return 0;
}

如果想要在文本内部换行可以直接在文本内部加上换行符,代码如下所示:

cpp 复制代码
#include <cstdio>
int main() 
{
 printf("Hello\nWorld\n");
 
 printf("Hello\n");
 printf("World\n");
 return 0;
}

(2)占位符

printf函数可以在输出文本指定占位符。所谓占位符就是这个位置可以用其他值替换。

cpp 复制代码
#include <cstdio>
// 输出 There are 3 apples 
int main()
{
 printf("There are %d apples\n", 3);
 return 0;
}

上述代码中,%d就是文本中的占位符,表示这个位置需要用接下来的参数进行替换。所有的占位符第一个符一律为%,第二个字符表示占位符的类型。%d表示需要替换成整型类型。printf函数的第二个参数是需要替换进文本的值,上面代码中3就会将%d进行替换,最终打印的结果为:There are 3 apples 。

cpp 复制代码
#include <cstdio>
int main()
{
 printf("%s will come tonight\n", "zhangsan");
 return 0;
}

常用的占位符有很多,上面%s占位符的数据类型为字符串类型。所以%s会被zhangsan替换掉,最终屏幕打印出:zhangsan will come tonight。

cpp 复制代码
#include <cstdio>
int main()
{
 printf("%s says it is %d o'clock\n", "lisi", 21);
 return 0;
}

占位符在文本中不仅可以有单个,也可以有多个。像上述代码所示:lisi和21会分别替换掉文本中的两个不同类型的占位符。

占位符列举:

|------|---------------------------------------------|
| 占位符 | 介绍 |
| %d | 十进制整数 |
| %lld | 十进制整数的long long int类型 |
| %f | 小数 |
| %Lf | long double类型浮点数 |
| %c | 字符 |
| %s | 字符串 |
| %a | 十六进制浮点数,字母输出为小写 |
| %A | 十六进制浮点数,字母输出为大写 |
| %e | 使用科学计数法的浮点数,指数部分e为小写 |
| %E | 使用科学计数法的浮点数,指数部分E为大写 |
| %i | 整数基本等同于%d |
| %g | 6个有效数字的浮点数。整数部分一旦超过6位,会自动转换为科学计数法,且指数部分e为小写 |
| %G | 6个有效数字的浮点数。整数部分一旦超过6位,会自动转换为科学计数法,且指数部分E为大写 |
| %hd | 十进制的short int类型 |
| %ho | 八进制的short int类型 |
| %hx | 十六进制的short int类型 |
| %hu | unsigned short int 类型 |
| %ld | 十进制的long int类型 |
| %lo | 八进制的long int类型 |
| %lx | 十六进制的long int类型 |
| %lu | unsigned long int 类型 |
| %llo | 八进制long long int类型 |
| %llx | 十六进制long long int 类型 |
| %llu | unsigned long long int 类型 |
| %Le | 科学计数法表示的 long double 类型浮点数 |
| %n | 已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中 |
| %o | 八进制整数 |
| %p | 指针 |
| %u | 无符号整数 |
| %x | 十六进制整数 |
| %zd | size_t类型 |
| %% | 输出一个% |

(3)格式化输出

printf函数可以定制占位符的输出格式。

<1>限定宽度

printf函数允许占位符限定最小宽度

cpp 复制代码
#include <cstdio>
int main()
{
 printf("%5d\n", 123); // 输出为 " 123" 
 return 0;
}

上述代码中,%5d表示这个占位符的宽度至少为5位,如果不满5位,对应值的前面会添加空格。输出的值默认为右对齐,即输出的内容前面会有空格;如果希望改成左对齐,需要将占位符的%后面添加一个符号-。

cpp 复制代码
#include <cstdio>
int main()
{
 printf("%-5d\n", 123); // 输出为 "123 " 
 return 0;
}

上面示例中,在占位符的%后面添加了符号,所以会左对齐,也就是说空格会在对应内容的后面加入。

cpp 复制代码
#include <cstdio>
// 输出 " 123.450000" 
int main()
{
 printf("%12f\n", 123.45);
 return 0;
}

上述代码中,%12f表示输出的浮点数至少占据12位。由于小数默认显示精度是小数后6位,所以输出的小数会在头部添加两个空格。

<2>限定小数位数

输出小数时,有时候希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符就可以写形成%.2f。

cpp 复制代码
#include <cstdio>
// 输出 Number is 0.50 
int main()
{
 printf("Number is %.2f\n", 0.5);
 return 0;
}

上述代码中,将占位符写成%.2f的形式,指的是小数点后保留两位小数。当然这种写法也可以结合限制宽度的占位符来使用,详细请看下方代码:

cpp 复制代码
#include <cstdio>
// 输出为 " 0.50" 
int main()
{
 printf("%6.2f\n", 0.5);
 return 0;
}

上述代码中,通过限制宽度和小数点后位数结合。%6.2f表示的是最小宽度为6,小数点后保留2位数字。所以输出的内容头部有两个空格。最小宽度和小数点后位数这两个限定值,都可以用*代替,类似于新的占位符。通过printf函数的参数传入,具体请看下方代码:

cpp 复制代码
#include <cstdio>
int main()
{
 printf("%*.*f\n", 6, 2, 0.5);
 return 0;
}
// 等同于printf("%6.2f\n", 0.5); 

上述代码中printf函数的前两个参数会替换掉文本中的*,从而达到限定宽度和小数点后位数的目的。

2.scanf函数

scanf函数的具体原型如下:

cpp 复制代码
int scanf ( const char * format, ... );

(1)基本用法

该函数用于读取用户的键盘输入。程序运行到该语句时,会暂停下来。等待用户从键盘输入。与用户输入数据,按下回车键后,该函数会处理用户的输入,将其存入变量中。等待接下来的访问。

cpp 复制代码
#include <cstdio>
int main()
{
 int i = 0;
 scanf("%d", &i);
 printf("%d\n", i);
 return 0;
}

根据上方代码可知:scanf函数的第一个参数是格式字符串,里面会放置占位符(与printf函数的占位符基本类似),用来告诉编译器接下来输入的数据是什么类型,用于准确的接收数据。(C语言数据都是有类型的,该函数必须提前知道用户输入的数据类型,才能进一步处理数据)。它的其余参数是存放用户输入的变量,格式字符串里面有多少个字符串,这里就有多少个变量

cpp 复制代码
#include <cstdio>
int main()
{
 int a, b, c, d;
 scanf("%d%d%d%d", &a, &b, &c, &d);
 printf("%d %d %d %d\n", a, b, c, d);
 return 0;
}

注意:scanf函数中指定的格式和给程序输入的数据格式要严格匹配,否则既不会得到想要的数值。

cpp 复制代码
#include <cstdio>
int main()
{
 int i = 0;
 int j = 0;
 float x = 0;
 float y = 0;
 scanf("%d%d%f%f", &i, &j, &x, &y);
 
 printf("i = %d\n", i);
 printf("j = %d\n", j);
 printf("x = %f\n", x);
 printf("y = %f\n", y);
 
 return 0;
}

上述代码中,格式字符串%d%d%f%f,表示用户输入的四个数据的数据类型。前两个是整数,后两个是浮点数。比如键盘输入:1 -20 3.4 -4.0e3。这四个数依次存放在i j x y四个变量中。

scanf函数处理数值占位符时,会自动过滤掉空白字符,所以用户输入的数据之间,有一个或者多个空格不影响函数的解读数据。

用户分成四行输入的话,得到的结果和一行输入的结果是完全一样的。每次按下回车键时,函数就会开始解读,如果第一行匹配第一个占位符,那么下次按回车时,就会从第二行开始解读。

scanf函数的处理逻辑:用户输入的内容先放入缓存中,等到按下回车键后,会按照占位符提示的类型对缓存进行解读。解读用户输入时,会从上一个解读遗留的第一个字符开始,知道解读完缓存,或者遇到第一个不符合条件的字符为止。

cpp 复制代码
#include <cstdio>
int main()
{
 int x = 0;
 float y = 0;
 
 // ⽤⼾输⼊ " -13.45e12# 0" 
 scanf("%d", &x);
 printf("%d\n", x);
 scanf("%f", &y);
 printf("%f\n", y);
 return 0;
}

上述示例中,函数读取输入时,%d会忽略掉开始的空格,从负号开始解读数据。读到-13停下来,因为接下来的点不满足%d的类型了。以此类推一共只会读取两个数:-13和0.15e12。由于scanf函数可以同时处理多个占位符,所以上面的代码也可以写成下方代码的样子:

cpp 复制代码
#include <stdio.h>
int main()
{
 int x = 0;
 float y = 0;
 
 // ⽤⼾输⼊ " -13.45e12# 0" 
 scanf("%d%f", &x, &y);
 printf("%d %f\n", x, y);
 return 0;
}

(2)占位符

scanf() 常⽤的占位符如下,与 printf() 的占位符基本⼀致。

|-----|------------------|
| 占位符 | 介绍 |
| %c | 字符 |
| %d | 整数 |
| %f | float类型浮点数 |
| %lf | double类型浮点数 |
| %Lf | long double类型浮点数 |
| %s | 字符串 |

上面所有的占位符之中,除了%c之外,都会自动忽略掉起首的空白字符。%c不会忽略空白字符,总是返回第一个字符。无论该字符是否为空格,如果要强制跳过字符前的空白字符,可以在占位符的%留个空格即可,表示跳过零个或多个空白字符。

cpp 复制代码
#include <cstdio>
int main()
{
 char ch = 0;
 scanf("%c", &ch);
 printf("--%c--\n", ch);
 return 0; 
}

在输入字符a之前,没有输入空白字符,函数就会读取到字符a;如果在前面输入了空白字符,那么函数就会读取这个空白字符。以至于最后打印时结果不同。为了避免读取空白字符,可以像下方代码那样:

cpp 复制代码
#include <cstdio>
int main()
{
 char ch = 0;
 scanf(" %c", &ch);//%c前⾯的空格会让scanf强制跳过空⽩字符,去读取⾮空⽩字符 
 printf("--%c--\n", ch);
 return 0; 
}

了解完上面的scanf函数的特性之后,当%c%d等占位符连续使用时,需要格外注意。%c默认不会跳过空白字符。

cpp 复制代码
#include <cstdio>
int main() 
{ 
 int a;
 char ch;
 scanf("%d%c", &a, &ch);
 printf("%d %c\n", a, ch);
 return 0; 
}

如果在输入的时候,就像在整数和字符之间加上空格,那么scanf中的格式串%c之前就要加上空格。

cpp 复制代码
#include <cstdio>
int main() 
{ 
 int a;
 char ch;
 scanf("%d %c", &a, &ch);//%c的前⾯加上空格,是强制跳过数据输⼊中的空⽩字符 
 printf("%d %c\n", a, ch);
 return 0; 
}

(3)返回值

函数的返回值是一个整数,表示成功读取变量的数量。如果没有读取任何项,或者匹配失败,则返回0.如果在成功读取任何数据之前,发生了读取错误或者遇到文件结尾,则返回常量EOF也就是整数-1。

cpp 复制代码
#include <cstdio>
int main()
{
 int a = 0;
 int b = 0;
 float f = 0.0f;
 int r = scanf("%d %d %f", &a, &b, &f);
 printf("a=%d b=%d f=%f\n", a, b, f);
 printf("r = %d\n", r);
 return 0;
}

如果输入两个数之后,点击Ctrl+z,提前结束输入:

通过上述图片可知:r=2,表示正确读取了两个数值。如果输入的数据一个都不能匹配成功的话,输出的r就会是0。

如果什么也不输入,直接点击Ctrl+z就可以发现r=-1,也就是我们所说的EOF。

三.cin和cout

前面我们提到过在C++语言中,提供了cin和cout两个流对象。

cin是C++语言中提供的标准输入流对象,一般针对的是键盘,也就是键盘上输入的字符流,使用cin来进行数据的提取,cin一般是和>>流提取运算符配合使用的。cin的功能和scanf是类似的。

cout是C++中提供的标准输出流对象,一般针对控制台的窗口,也就是将数据以字符流的形式输出到控制台窗口上显示。cout一般和流插入运算符配合使用。cout的功能和printf功能是类似的。

所以我们在写程序的时候,经常需要处理数据,不管什么类型的数据都是以字符流的形式输入和输出的,也就是不管在键盘上输入什么类型的数据,还是将程序中的各种类型数据输出显示在控制台屏幕上,都是以字符流的形式处理的。cin和cout的输入和输出非常方便,不需要手动控制格式,能够自动识别变量类型。

1.基本用法

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
 int a;
 char c;
 float f;
 
 cin >> a; // 读取⼀个整数 
 cin >> c; // 读取⼀个字符 
 cin >> f; // 读取取⼀个浮点数 
 
 cout << "打印结果:"<<endl;
 cout << a << endl;
 cout << c << endl;
 cout << f << endl;
 return 0;
}

当我们在键盘上输入数据时,输入的数据不能被cin解读为对应的数据时,那么读取也就结束了。具体详看下方图片:

cin函数的使用细节:cin函数在读取的时候是根据用户的输入,从前往后,从上向下依次扫描。cin函数在读取的过程中遇到空格会自动跳过,所以不用担心在想要的字符前输入空白字符。当一行读取结束时,会自动换行,读取下一行内容。

2.连续输入输出

如果我们一次要输入输出多个数据时,cin和cout函数也可以做到!

cin函数例子:

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
 int a = 0;
 int b = 0;
 //同类型变量连续输⼊ 
 cin >> a >> b; //以最后⼀次
输⼊为准 
 
 //添加换⾏endl 
 cin >> a >> endl; //代码编译报错 
 
 return 0;
}
cpp 复制代码
#include <iostream> 
using namespace std; 
int main() 
{ 
 //不同类型变量的连续输⼊ 
 int a = 0; 
 char ch = 0; 
 float f = 0; 
 cin >> a >> ch >> f; 
  
 return 0; 
} 

cout函数例子:

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
 //对同⼀类型变量连续输出 
 int a = 10;
 int b = 20
 cout << a << " " << b << 
endl;
 return 0;
}
cpp 复制代码
#include <iostream> 
using namespace std; 
int main() 
{ 
 //⽀持相同/不同类型变量的连续输⼊ 
 char ch = 0; 
 float f = 0.1; 
 cout << ch << f << endl; 
  
 //格式化输出:添加(任意)空格和字符串 
 cout << "ch:" << ch << " f:" << 
f << endl; 
  
 //格式化输出:多次换⾏ 
 cout << ch << endl << endl; 
 return 0; 
}

cin函数的优点:

当输入若干个变量的时候,我们可以通过>>把所有的数据用一行代码完成接收,而且不需要关心数据的类型,和scanf函数比较起来更加方便。

cout函数的优点:

函数可以用来连续输出多个数值,而且不需要考虑数值的类型,因为它本身会做类型处理,和printf函数相比较更加方便。

相关推荐
C++ 老炮儿的技术栈1 小时前
Qt中自定义 QmyBattery 电池组件开发
c语言·开发语言·c++·windows·qt·idea·visual studio
Dxy12393102161 小时前
Python的PIL如何转Base64字符串:完整指南
开发语言·python
Howrun7771 小时前
Linux_C++_日志实例
linux·运维·c++
头发还没掉光光1 小时前
C语言贪吃蛇:基于Linux中ncurses库实的贪吃蛇小游戏
linux·c语言·开发语言
fie88892 小时前
基于MATLAB的时变Copula实现方案
开发语言·matlab
冬奇Lab2 小时前
【Kotlin系列12】函数式编程在Kotlin中的实践:从Lambda到函数组合的优雅之旅
android·开发语言·kotlin
写代码的【黑咖啡】2 小时前
Python中的Msgpack:高效二进制序列化库
开发语言·python
梵尔纳多2 小时前
第一个 3D 图像
c++·图形渲染·opengl
Jaxson Lin2 小时前
Java编程进阶:线程基础与实现方式全解析
java·开发语言