C++中的字符串和格式化输入/输出

发布于:2023-01-09 ⋅ 阅读:(895) ⋅ 点赞:(0)

       关于C++,基础的概念便可不在叙述,这篇文章主要围绕于 C++中字符串相关内容 和 格式化输入\输出 ,那么,将离不开包含在头文件 stdio.h 中的 printf() 函数和 scanf() 函数。如果能够利用好这两个函数,那么不仅能与用户交互,还可根据个人喜好和任务要求格式化输出。

       首先,我们先来了解字符串

      1.1 字符串

       字符串(character string)是一或多个字符的序列,例如  "Welcome to Shaanxi!" ,它用双引号括起来,双引号的作用则是告知编译器它括起来的是字符串。关于字符串的储存,我将用一幅图来表示:

W e l c o m e   t o   S h a a n x i ! \0

C语言中字符串都是被储存在char类型的数组中,如上图所示,字符串中的每一个字符被储存在相邻的储存单元中,包括空字符 '\0' ,它用来标记字符串的结束。接下来,我们将通过一个简单的例子(程序1.1)来使用字符串,我使用的编译器是MSVS2022。

#include<stdio.h>
#include<string.h>
int main(void)
{
	char name[40];

	printf("你的名字是:");
	scanf("%s", name);
	printf("你好,%s.今天的你又比昨天更加努力了噢!\n", name);
	printf("你的名字占用%zd个字节", strlen(name));

	return 0;
}

输入zhangsan,打印出来结果是:

b0d1a4fd07334b2a850e329d5c5deae4.png

 

这段代码中,输入的名字zhangsan以 %s 的形式打印出来,它在储存中占用9个字节,因为空字符'\0'的存在。

       1.2 strlen()函数与sizeof运算符的区别

       在程序1.1中,我们使用了包含在头文件string.h中的strlen()函数。由于sizeof以字节为单位给出对象的大小,而strlen()函数给出字符串中的字符长度(一个字符储存在一个字节中),那么,将这两种方法同时应用于字符串能否得到相同结果呢?答案显然是否定的。我将通过下面一个例子(程序1.2)来说明:

#include<stdio.h>
#include<string.h>
#define SENTENCE "Welcome to Shaanxi!"
int main(void)
{
	char name[40];

	printf("尊敬的旅客,请输入您的名字:");
	scanf("%s", name);
	printf("请稍等,正在查询信息中……\n");
	Sleep(5000);//Sleep()函数,程序将延时5s打印下一项
	printf("%s,欢迎来到陕西!(%s)\n", name, SENTENCE);

	printf("\n\"用sizeof运算符得出名字占用 %zd 个字节,", sizeof(name));
	printf("而strlen()函数得出名字占用 %zd 个字节。\"\n", strlen(name));
	printf("\"用sizeof运算符得出SENTENCE占用 %zd 个字节,", sizeof(SENTENCE));
	printf("而strlen()函数得出SENTENCE占用 %zd 个字节。\"\n", strlen(SENTENCE));

	return 0;
}

代码中 Sleep() 函数用于延时打印下一项printf,其中5000单位为毫秒。运行代码,根据提示输入名字:Zhangsan,得到如下结果:

7f6703ace7ca4f60a77710b90a2f8713.png

 其中,sizeof运算符得出名字占用40个字节,其实是name数组中有40个储存单元,但是只有前8个存储Zhangsan,因此strlen()函数得出名字占用8个字节是正确的;下面关于SENTENCE所占字节数,由于sizeof也将空字符 '\0' 包括在内,所以比strlen(SENTENCE)多一个字节。通过这个例子,我们可以直观地看出 sizeof运算符strlen()函数 的区别。

       1.3 #define 指令

       程序1.2中运用 #define 指令将字符串" Welcome to Shaanxi! "用 SENTENCE 代替。其中 SENTENCE 叫做符号常量。那么,常量与符号常量在应用上的区别主要体现在哪里呢?我们在敲代码时,离不开常量的应用,但是如果涉及那种会经常改变的常量,例如税率,使用常量表示税率,当税率发生变化时,则应该把程序中所有的税率常量都改变,但是如果对于这种经常变化的常量使用符号常量的话,使用符号常量,当发生变化时,我们只需要改变符号常量的定义即可。

        那么,如何创建符号常量?其通用格式如下:

       #define NAME value

       其中NAME表示符号常量名,value表示符号常量的值,并且末尾不用加分号。

        1.4 printf()函数 和 scanf()函数

        1.4.1 printf()函数

        我们在使用 printf() 函数时,打印的数据的指令要与待打印数据类型相匹配。例如,打印整数时使用%d,打印字符使用%c,打印字符串使用%s。这些符号被称为转换说明。接下来我将通过一个表格(表1.1)将部分转换说明陈列在其中:
 

表1.1   转换说明及其打印的输出结果
转换说明 输出
%% 打印一个百分号
%c 单个字符
%d 有符号十进制整数
%e 浮点数,e计数法
%E 浮点数,e计数法
%f 浮点数,十进制计数法
%i 有符号十进制整数(与%d相同)
%o 无符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制整数
%x 无符号十六进制整数
%X 无符号十六进制整数
%a 浮点数,十六进制数和p计数法
%A 浮点数,十六进制数和p计数法

程序1.3使用了一些转换说明:

#include<stdio.h>
#define PI 3.1415926
int main(void)
{
	int radius = 0;//定义变量半径,并初始化为零
	double area;//定义变量圆面积
	double circum;//定义变量圆周长

	printf("请输入想要求的圆面积的半径:");
	scanf("%d", &radius);

	area = PI * radius * radius;
	circum = 2.0 * PI * radius;

	printf("半径为%d的圆面积为%4.5f.\n", radius, area);
	printf("该圆周长为%4.5f.\n", circum);

	return 0;
}

输入圆半径为 5 .得到输出结果如下:

c431b091a5c94e73bf1cda9bc0dfeecf.png

 其中面积(area)与周长(circum)为双精度型浮点数,用%f打印,其中 %4.5f 中的4表示打印项输出结果为4个字段宽度,由于待打印的数宽度超过了4,所以字段宽度自动扩大为带打印项字段宽度,其中 .5 表示精确到小数点后五位。

          程序1.3中使用了%4.5f转换说明,其也可以理解为转换说明修饰符,接下来,我将用表格(表1.2)列出一些printf()的修饰符。

      

表1.2   printf()的修饰符
修饰符 含义
标记 表1.3描述了5中常见的标记
数字 最小字段宽度
. 数字 精度
h 和整型转换说明一起使用,表示 short int 或 unsigned short int 类型的值。如 "%hu","%hx"
hh 和整型转换说明一起使用,表示 signed char 或 unsigned char 类型的值。如 "%hhu","%hhx"
l 和整型转换说明一起使用,表示 long int 或 unsigned long int 类型的值。如 "%lu","%ld"
ll 和整型转换说明一起使用,表示 long long int 或 unsigned long long int 类型的值。如 "%llu","%lld"
L 和浮点转换说明一起使用,表示 long double 类型的值。如 "%Lf"
z 和整型转换说明一起使用,表示 size_t 类型的值,该类型是 sizeof 返回的类型

下面的 表1.3 列出printf()函数中常用的标记

表1.3 printf()中的标记
标记 含义
- 从字段的左侧开始打印该项
+ 有符号值若为正,则在值前面显示加号,若为负,在值前面显示减号
空格 有符号值若为正,则在值前面显示前导空格(不显示任何符号),若为负,在值前面显示减号标记并覆盖空格
# 把结果转换为另一种形式
0

对于数值格式,用前导0代替空格填充字段宽度。

对于整数格式,如果出现-标记或指定精度,则忽略

接下来,我们通过程序1.4来了解修饰符和标记

#include<stdio.h>
#define PAGES 959
int main(void)
{
	printf("*%d*\n", PAGES);
	printf("*%2d*\n", PAGES);
	printf("*%10d*\n", PAGES);
	printf("*%-10d*\n", PAGES);

	return 0;
}

该程序中使用*标记字段的开始与结束,让我们更加直观的看出标记和修饰符的作用。打印结果如下:

49701bf2fa5040f6a96fc02fa169e3c5.png

该程序中,"%2d"由于959字段宽度为三,它将自动扩充;"%-10d"打印字段宽度为10并且从左端开始打印。

 程序1.5展示出字符串格式的示例

#include<stdio.h>
#define BLURB "Welcome to Shaanxi!"
int main(void)
{
	printf("[%2s]\n", BLURB);
	printf("[%24s]\n", BLURB);
	printf("[%20s]\n", BLURB);
	printf("[%24.2s]\n", BLURB);
	printf("[%24.3s]\n", BLURB);
	printf("[%24.4s]\n", BLURB);
	printf("[%24.5s]\n", BLURB);
	printf("[%-24.5s]\n", BLURB);

	return 0;
}

e38be82351b847eeb3b3fe0130bc58e8.png

 该程序与程序1.4有同样的表达,展示了修饰符和标记的示例。

         1.4.2 转换说明的意义

         转换说明把以二进制格式储存在计算机中的值转换为一系列字符(字符串)以便于显示,它很容易被我们误解为原始值被替换成转换后的值。实际上,转换说明是翻译说明。例如,%d的意思是“把给定的值翻译成十进制文本并打印出来”。

        1.4.3 scanf() 函数

        C库中包含多个输入函数,scanf() 函数是最通用的一个,因为它可以读取不同格式的数据。它与 printf() 函数类似,也使用格式字符串和参数列表,scanf() 函数中的格式字符串字符输入流的目标数据类型。scanf() 和 printf()的区别主要在于参数列表中,printf() 函数使用变量,常量和表达式,而 scanf() 函数使用指针变量的指针。这里有两条简单的规则:

       ·1.   如果用scanf()读取基本变量类型的值,在变量名前加一个 &

       ·2.   如果用scanf()把字符串读入字符数组中,不要使用 &

       程序1.6展示了这两条规则:

​
#include<stdio.h>
int main(void)
{
	int age;        //变量
	char pet[20];   //字符数组,用于储存字符串

	printf("请输入你的年龄:");
	scanf("%d", &age);//基本变量使用&
	printf("你好呀,%d岁的小朋友,你最喜欢的宠物是什么?\n",age);
	scanf("%s", pet);//字符数组不使用&
	printf("有这么可爱的你,那么%s一定也非常可爱吧!", pet);

	return 0;
}

​

其输入年龄:8,最喜欢的宠物:小狗。打印结果如下:

230e043b5010471c9e63b9c9989d4a6e.png

 scanf()函数所用的转换说明与printf()函数基本相同,我将用一个表格(表1.4)列出常见的转换说明

表1.4 scanf()的转换说明
转换说明 含义
%c 把输入解释成字符
%d 把输入解释成有符号的十进制整数
%e,%f,%g,%a 把输入解释成浮点数
%E,%F,%G,%A 把输入解释成浮点数
%i 把输入解释成有符号的十进制整数
%o 把输入解释成有符号的八进制整数
%p 把输入解释成指针(地址)
%s 把输入解释成字符串,第一个空白开始,下一个空白结束
%u 把输入解释成无符号十进制整数
%x,%X 把输入解释成有符号的十六进制整数

下面这个表格(表1.5)我将列出scanf()函数转换说明中的修饰符

表1.4 scanf() 转换说明中的修饰符
修饰符 含义
* 抑制赋值
数字 最大字段宽度
hh 把整数作为 signed char 或 unsigned char 类型读取,如:"%hhd"
ll 把整数作为 long long或 unsigned long long 类型读取,如:"%lld"
j 在类型转换说明后面时,表明使用 intmax_t 或 uintmax_t 类型,如:"%jd"
z 在类型转换说明后面时,表明使用sizeof的返回值类型,如:"%zd"
t 在类型转换说明后面时,表明使用两个指针差值的类型,如:"%td"

实际上,scanf() 函数并不是最常用的输入函数,它只是能读取不同类型的数据。C语言中还有其他的输入函数,如 getchar() 和 fgets() 。

如果本篇文章有任何错误希望兄弟们指正,谢谢啦!

 

 

本文含有隐藏内容,请 开通VIP 后查看