C primer plus 学习笔记_第四章 字符串和格式化输入/输出

第4章 字符串和格式化输入/输出

函数:strlen()
关键字:const
用C预处理器指令#define和ANSIC的const修饰符创建符号常量
————————————————————————————————————————————————————————————

4.1 前导程序

// talkback.c -- 演示与用户交互
#include <stdio.h>
#include <string.h> // 提供strlen()函数的原型
#define DENSITY 62.4 // 人体密度(单位:磅/立方英尺)
int main()
{
float weight, volume;
int size, letters;
char name[40]; // name是一个可容纳40个字符的数组
printf("Hi! What's your first name?\n");
scanf("%s", name);
printf("%s, what's your weight in pounds?\n", name);
scanf("%f", &weight);
size = sizeof name;
letters = strlen(name);
volume = weight / DENSITY;
printf("Well, %s, your volume is %2.2f cubic feet.\n",
name, volume);
printf("Also, your first name has %d letters,\n",
letters);
printf("and we have %d bytes to store it.\n", size);
return 0;
}

运行talkback.c程序,输入结果如下:
Hi! What’s your first name?
Christine
Christine, what’s your weight in pounds?
154
Well, Christine, your volume is 2.47 cubic feet.
Also, your first name has 9 letters,
and we have 40 bytes to store it.

该程序包含以下新特性:
用数组(array)储存字符串(character string)。在该程序中,用户输入的名被储存在数组中,该数组占用内存中40个连续的字节,每个字节储存一个字符值。

使用%s转换说明来处理字符串的输入和输出。注意,在scanf()中,name没有&前缀,而weight有。

用C预处理器把字符常量DENSITY定义为62.4。

用C函数strlen()获取字符串的长度。
————————————————————————————————————————————————————————————

4.2字符串简介

字符串(character string)是一个或多个字符的序列。

双引号告知编译器它括起来的是字符串,正如单引号用于标识单个字符一样。

4.2.1 char类型数组和null字符

C语言没有专门用于储存字符串的变量类型,字符串都被储存在char类型的数组中。数组由连续的存储单元组成,字符串中的字符被储存在相邻的存储单元中,每个单元储存一个字符。
数组中的字符串
\0空字符(null character),C语言用它标记字符串的结束。空字符不是数字0,它是非打印字符,其ASCII码值是(或等价于)0。

C中的字符串一定以空字符结束,这意味着数组的容量必须至少比待存储字符串中的字符数多1。

数组是同类型数据元素的有序序列。在声明变量中,变量名后的[]表面这是一个数组,[]中的数字表示该数组中的元素数量。
声明一个变量和声明一个数组

4.2.2 使用字符串

/* praise1.c -- 使用不同类型的字符串 */
#include <stdio.h>
#define PRAISE "You are an extraordinary being."
int main(void)
{
char name[40];
printf("What's your name? ");
scanf("%s", name);
printf("Hello, %s.%s\n", name, PRAISE);
return 0;
}

运行praise1.c,其输出如下所示:
What’s your name? Angela Plains
Hello, Angela.You are an extraordinary being.

%s告知printf()函数要打印的变量为字符串。

scanf()只读取了Angela Plains中的Angela,它在遇到第1个空白(空格、制表符或换行符)时就不再读取输入。一般而言,根据%s转换说明,scanf()只会读取字符串中的一个单词,而不是一整句。
字符串和字符
字符串常量"x"和字符常量’x’不同。区别之一在于’x’是基本类型(char),而"x"是派生类型(char数组);区别之二是"x"实际上由两个字符组成:'x’和空字符\0。
字符'x'和字符串"x"

4.2.3 strlen()函数

strlen() 函数给出字符串中的字符长度。

/* praise2.c */
// 如果编译器不识别%zd,尝试换成%u或%lu。
#include <stdio.h>
#include <string.h> /* 提供strlen()函数的原型 */
#define PRAISE "You are an extraordinary being."
int main(void)
{
char name[40];
printf("What's your name? ");
scanf("%s", name);
printf("Hello, %s.%s\n", name, PRAISE);
printf("Your name of %zd letters occupies %zd memory cells.\n",
strlen(name), sizeof name);
printf("The phrase of praise has %zd letters ",
strlen(PRAISE));
printf("and occupies %zd memory cells.\n", sizeof PRAISE);
return 0;
}

如果使用ANSI C之前的编译器,必须移除这一行:

#include <string.h>

运行该程序,其交互输出如下:
What’s your name? Serendipity Chance
Hello, Serendipity.You are an extraordinary being.
Your name of 11 letters occupies 40 memory cells.

string.h头文件包含多个与字符串相关的函数原型,包括strlen()。

printf()函数中可以在参数之间断为两行,但是不要在双引号中的字符串中间断开。

sizeof运算符报告,name数组有40个存储单元。但是,只有前11个单元用来储存Serendipity,所以strlen()得出的结果是11。name数组的第12个单元储存空字符,strlen()并未将其计入。
strlen()函数知道在何处停止
对于 PRAISE,用 strlen()得出的也是字符串中的字符数(包括空格和标点符号)。然而,sizeof运算符给出的数更大,因为它把字符串末尾不可见的空字符也计算在内。

当sizeof的运算对象是类型关键字时,圆括号必不可少,但是对于特定量,可有可无。如size(int),sizeof 3.14,sizeof (3.14),sizeof name,sizeof (name)。
建议:无论sizeof的运算对象是否为类型关键字,最好都加上圆括号.
————————————————————————————————————————————————————————————

4.3 常量和C预处理器

#define Pi 3.14159

或者

float Pi;
Pi=3.14159;

上面的Pi为符号常量(symbolic constant),用来将代码中所有的Pi替换为3.14159。

使用符号常量的好处:
1.常量名比数字表达的信息更多。
2.假设程序中的多处使用一个常量,有时需要改变它的值。如果程序使用符号常量,则只需更改符号常量的定义,不用在程序中查找使用常量的地方,然后逐一修改。
创建符号常量的方法:
1.声明一个变量,然后将该变量设置为所需的常量(由于是变量,在程序执行过程中可能变量的值遭到改变)。
2.使用C预处理器,在程序顶部添加#define 符号常量名 符号常量对应的值。
建议:在C预处理器添加符号常量时,变量名最好大写,向程序员表明这是一个符号常量,或者给符号常量名加前缀_c或_k

编译程序时,程序中所有的符号常量名都会被替换成其对应值。这一过程被称为编译时替换(compile-time substitution)。在运行程序时,程序中所有的替换均已完成。通常,这样定义的常量也称为明示常量(manifest constant)。
输入的内容和编译后的内容

/* pizza.c -- 在比萨饼程序中使用已定义的常量 */
#include <stdio.h>
#define PI 3.14159
int main(void)
{
float area, circum, radius;
printf("What is the radius of your pizza?\n");
scanf("%f", &radius);
area = PI * radius * radius;
circum = 2.0 * PI *radius;
printf("Your basic pizza parameters are as follows:\n");
printf("circumference = %1.2f, area = %1.2f\n", circum,area);
return 0;
}

下面是一个输出示例:
What is the radius of your pizza?
6.0
Your basic pizza parameters are as follows:
circumference = 37.70, area = 113.10

#define指令还可定义字符和字符串常量。前者使用单引号,后者使用双引号。

4.3.1 const限定符

C90标准新增了const关键字,用于限定一个变量为只读(可以使用、打印该变量,但不能改变该变量的值)。

4.3.2 明示常量

C头文件limits.h和float.h分别提供了与整数类型和浮点类型大小限制相关的详细信息。每个头文件都定义了一系列供实现使用的明示常量 。
limits.h中的一些明示常量
类似地,float.h头文件中也定义一些明示常量来分别表示float类型和double类型的有效数字位数。
float.h中的一些明示常量
把明示常量名中的FLT分别替换成DBL和LDBL,即可分别表示double和long double类型对应的明示常量。

// defines.c -- 使用limit.h和float头文件中定义的明示常量
#include <stdio.h>
#include <limits.h> // 整型限制
#include <float.h> // 浮点型限制
int main(void)
{
printf("Some number limits for this system:\n");
printf("Biggest int: %d\n", INT_MAX);
printf("Smallest long long: %lld\n", LLONG_MIN);
printf("One byte = %d bits on this system.\n", CHAR_BIT);
printf("Largest double: %e\n", DBL_MAX);
printf("Smallest normal float: %e\n", FLT_MIN);
printf("float precision = %d digits\n", FLT_DIG);
printf("float epsilon = %e\n", FLT_EPSILON);
return 0;
}

该程序的输出示例如下:
Some number limits for this system:
Biggest int: 2147483647
Smallest long long: -9223372036854775808
One byte = 8 bits on this system.
Largest double: 1.797693e+308
Smallest normal float: 1.175494e-38
float precision = 6 digits
float epsilon = 1.192093e-07
————————————————————————————————————————————————————————————

4.4 printf()和scanf()

printf()函数和scanf()函数能让用户可以与程序交流,它们是输入/输出函数,或简称为I/O函数。两个函数都使用格式字符串和参数列表。

4.4.1 printf()函数

转换说明及其打印的输出结果

4.4.2 使用printf()

/* printout.c -- 使用转换说明 */
#include <stdio.h>
#define PI 3.141593
int main(void)
{
int number = 7;
float pies = 12.75;
195
int cost = 7800;
printf("The %d contestants ate %f berry pies.\n", number,
pies);
printf("The value of pi is %f.\n", PI);
printf("Farewell! thou art too dear for my possessing,\n");
printf("%c%d\n", '$', 2 * cost);
return 0;
}

该程序的输出如下:
The 7 contestants ate 12.750000 berry pies.
The value of pi is 3.141593.
Farewell! thou art too dear for my possessing,
$15600

printf()函数的格式
printf( 格式字符串, 待打印项1, 待打印项2,…);

待打印项1、待打印项2等都是要打印的项。它们可以是变量、常量,甚至是在打印之前先要计算的表达式。格式字符串应包含每个待打印项对应的转换说明。
printf()的参数
剖析格式字符串
由于 printf()函数使用%符号来标识转换说明,因此C语言规定用%%来打印一个%字符。

4.4.3 printf()的转换说明修饰符

在%和转换字符之间插入修饰符可修饰基本的转换说明。
printf()的修饰符
注意类型可移植性
注意float参数的转换(为保护大量假设float类型的参数被自动转换成double的现有程序,printf()函数中所有float类型的参数仍自动转换成double类型,因此没有float型专用的转换说明)
示例

/* width.c -- 字段宽度 */
#include <stdio.h>
#define PAGES 959
int main(void)
{
printf("(%d)\n", PAGES);
printf("(%2d)\n", PAGES);
printf("(%10d)\n", PAGES);
return 0;
printf("(%-10d)\n", PAGES);
}

其输出结果如下所示:
(959)
(959)
( 959)
(959 )

// floats.c -- 一些浮点型修饰符的组合
#include <stdio.h>
int main(void)
{
const double RENT = 3852.99; // const变量
printf("*%f*\n", RENT);
printf("*%e*\n", RENT);
printf("*%4.2f*\n", RENT);
printf("*%3.1f*\n", RENT);
printf("*%10.3f*\n", RENT);
printf("*%10.3E*\n", RENT);
printf("*%+4.2f*\n", RENT);
printf("*%010.2f*\n", RENT);
return 0;
}

该程序的输出如下:
(3852.990000)
(3.852990e+03)
(3852.99)
(3853.0)
( 3852.990)
( 3.853E+03)
(+3852.99)
(0003852.99)

/* flags.c -- 演示一些格式标记 */
#include <stdio.h>
int main(void)
{
printf("%x %X %#x\n", 31, 31, 31);
printf("(%d**% d**% d**\n", 42, 42, -42);
printf("(%5d**%5.3d(%05d**%05.3d**\n", 6, 6, 6, 6);
return 0;
}

该程序的输出如下:
1f 1F 0x1f
(42** 42**-42**
( 6** 006(00006** 006**

第3行输出演示了如何在整型格式中使用精度(%5.3d)生成足够的前导0以满足最小位数的要求,如用三位数006的格式来输出6。然而,使用0标记会使得编译器用前导0填充满整个字段宽度。

最后,如果0标记和精度一起出现,0标记会被忽略。

/* stringf.c -- 字符串格式 */
#include <stdio.h>
#define BLURB "Authentic imitation!"
int main(void)
{
printf("[%2s]\n", BLURB);
printf("[%24s]\n", BLURB);
printf("[%24.5s]\n", BLURB);
printf("[%-24.5s]\n", BLURB);
return 0;
}

该程序的输出如下:
[Authentic imitation!]
[ Authentic imitation!]
[ Authe]
[Authe ]

精度限制了待打印字符的个数。.5告诉printf()只打印5个字符。

4.4.4 转换说明的意义

转换说明把以二进制格式储存在计算机中的值转换成一系列字符(字符串)以便于显示。

1.转换不匹配

转换说明应该与待打印值的类型相匹配。

/* intconv.c -- 一些不匹配的整型转换 */
#include <stdio.h>
#define PAGES 336
#define WORDS 65618
int main(void)
{
short num = PAGES;
short mnum = -PAGES;
printf("num as short and unsigned short: %hd %hu\n", num,num);
printf("-num as short and unsigned short: %hd %hu\n", mnum,mnum);
printf("num as int and char: %d %c\n", num, num);
printf("WORDS as int, short, and char: %d %hd %c\n",WORDS,WORDS,
WORDS);
return 0;
}

在我们的系统中,该程序的输出如下:
num as short and unsigned short: 336 336
-num as short and unsigned short: -336 65200
num as int and char: 336 P
WORDS as int, short, and char: 65618 82 R

第二行中出现65200的原因
首先,short int的大小是2字节;

其次,系统使用二进制补码来表示有符号整数。这种方法,数字0~32767代表它们本身,而数字32768~65535则表示负数。其中,65535表示-1,65534表示-2,以此类推。因此,-336表示为65200(即,65536-336)。

第三行出现P的原因
在我们的系统中,short int是2字节,char是1字节。当printf()使用%c打印336时,它只会查看储存336的2字节中的后1字节。这种截断相当于用一个整数除以256,只保留其余数。在这种情况下,余数是80,对应的ASCII值是字符P。用专业术语来说,该数字被解释成“以256为模”(modulo 256),即该数字除以256后取其余数。
把336转换成字符
第四行输出异常原因类似第三行

/* floatcnv.c -- 不匹配的浮点型转换 */
#include <stdio.h>
int main(void)
{
float n1 = 3.0;
double n2 = 3.0;
long n3 = 2000000000;
long n4 = 1234567890;
printf("%.1e %.1e %.1e %.1e\n", n1, n2, n3, n4);
printf("%ld %ld\n", n3, n4);
printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);
return 0;
}

在我们的系统中,该程序的输出如下:
3.0e+00 3.0e+00 3.1e+46 1.7e+266
2000000000 1234567890
0 1074266112 0 1074266112

出错原因
转换说明与待打印项数据类型的位数不同,编译器读错指定数据的位数(只转化指定数据位数的一部分或者将指定数据位数相邻的位数也转化了)。且前面的数据的位数读错会导致后面的数据输出也异常。

参数传递
程序把传入的值放入被称为栈(stack)的内存区域。计算机根据变量类型(不是根据转换说明)把这些值放入栈中。函数根据转换说明(不是根据变量类型)从栈中读取值。
传递参数

2.printf()的返回值

大部分C函数都有一个返回值,这是函数计算并返回给主调程序(calling program)的值。printf()函数也有一个返回值,它返回打印字符的个数。如果有输出错误,printf()则返回一个负值(printf()的旧版本会返回不同的值)。

printf()的返回值是其打印输出功能的附带用途,通常很少用到,但在检查输出错误时可能会用到(如,在写入文件时很常用)。

/* prntval.c -- printf()的返回值 */
#include <stdio.h>
int main(void)
{
int bph2o = 212;
int rv;
rv = printf("%d F is water's boiling point.\n", bph2o);
printf("The printf() function printed %d characters.\n",
rv);
return 0;
}

该程序的输出如下:
212 F is water’s boiling point.
The printf() function printed 32 characters.

首先,程序用rv = printf(…);的形式把printf()的返回值赋给rv。因此,该语句执行了两项任务:打印信息和给变量赋值。其次,注意计算针对所有字符数,包括空格和不可见的换行符(\n)。

3.打印较长的字符串
/* longstrg.c ––打印较长的字符串 */
#include <stdio.h>
int main(void)
{
printf("Here's one way to print a ");
printf("long string.\n");
printf("Here's another way to print a \
long string.\n");
printf("Here's the newest way to print a "
"long string.\n"); /* ANSI C */
return 0;
}

该程序的输出如下:
Here’s one way to print a long string.
Here’s another way to print a long string.
Here’s the newest way to print a long string.

给字符串断行的3种方法:
方法1:使用多个printf()语句。因为第1个字符串没有以\n字符结束,所以第2个字符串紧跟第1个字符串末尾输出。

方法2:用反斜杠(\)和Enter(或Return)键组合来断行。这使得光标移至下一行,而且字符串中不会包含换行符。其效果是在下一行继续输出。但是,下一行代码必须和程序清单中的代码一样从最左边开始。如果缩进该行,比如缩进5个空格,那么这5个空格就会成为字符串的一部分。

方法3:ANSI C引入的字符串连接。在两个用双引号括起来的字符串之间用空白隔开,C编译器会把多个字符串看作是一个字符串。

4.4.5 使用scanf()

C库包含了多个输入函数,scanf()是最通用的一个,因为它可以读取不同格式的数据。

scanf()把输入的字符串转换成整数、浮点数、字符或字符串,而printf()正好与它相反,把整数、浮点数、字符和字符串转换成显示在屏幕上的文本。

scanf()和 printf()类似,也使用格式字符串和参数列表。scanf()中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()函数使用变量常量和表达式,而scanf()函数使用指向变量的指针。

如果用scanf()读取基本变量类型的值,在变量名前加上一个&;如果用scanf()把字符串读入字符数组中,不要使用&。

// input.c -- 何时使用&
#include <stdio.h>
int main(void)
{
int age; // 变量
float assets; // 变量
char pet[30]; // 字符数组,用于储存字符串
printf("Enter your age, assets, and favorite pet.\n");
scanf("%d %f", &age, &assets); // 这里要使用&
scanf("%s", pet); // 字符数组不使用&
printf("%d $%.2f %s\n", age, assets, pet);
return 0;
}

下面是该程序与用户交互的示例:
Enter your age, assets, and favorite pet.
38
218
92360.88 llama
38 $92360.88 llama

scanf()函数所用的转换说明与printf()函数几乎相同。主要的区别是,对于float类型和double类型,printf()都使用%f、%e、%E、%g和%G转换说明。而scanf()只把它们用于float类型,对于double类型时要使用l修饰符。
ANSI C中scanf()的转换说明
scanf()转换说明中的修饰符
scanf()转换说明中的修饰符

1.从scanf()角度看输入

假设scanf()根据一个%d转换说明读取一个整数。scanf()函数每次读取一个字符,跳过所有的空白字符,直至遇到第1个非空白字符才开始读取。因为要读取整数,所以scanf()希望发现一个数字字符或者一个符号(+或-)。如果找到一个数字或符号,它便保存该字符,并读取下一个字符。如果下一个字符是数字,它便保存该数字并读取下一个字符。scanf()不断地读取和保存字符,直至遇到非数字字符。如果遇到一个非数字字符,它便认为读到了整数的末尾。然后,scanf()把非数字字符放回输入。这意味着程序在下一次读取输入时,首先读到的是上一次读取丢弃的非数字字符。最后scanf()计算已读取数字(可能还有符号)相应的数值,并将计算后的值放入指定的变量中。

如果使用字段宽度,scanf()会在字段结尾或第1个空白字符处停止读取(满足两个条件之一便停止)。

如果第1个非空白字符是A而不是数字,scanf()将停在那里,并把A放回输入中,不会把值赋给指定变量。程序在下一次读取输入时,首先读到的字符是A。如果程序只使用%d转换说明, scanf()就一直无法越过A读下一个字符。另外,如果使用带多个转换说明的scanf(),C规定在第1个出错处停止读取输入。

用其他数值匹配的转换说明读取输入和用%d 的情况相同。区别在于scanf()会把更多字符识别成数字的一部分。例如,%x转换说明要求scanf()识别十六进制数a~f和A~F。浮点转换说明要求scanf()识别小数点、e记数法(指数记数法)和新增的p记数法(十六进制指数记数法)。

如果使用%s 转换说明,scanf()会读取除空白以外的所有字符。scanf()跳过空白开始读取第 1 个非空白字符,并保存非空白字符直到再次遇到空白。这意味着 scanf()根据%s 转换说明读取一个单词,即不包含空白字符的字符串。如果使用字段宽度,scanf()在字段末尾或第1个空白字符处停止读取。无法利用字段宽度让只有一个%s的scanf()读取多个单词。最后要注意一点:当scanf()把字符串放进指定数组中时,它会在字符序列的末尾加上’\0’,让数组中的内容成为一个C字符串。

2.格式字符串中的普通字符

scanf()函数允许把普通字符放在格式字符串中。除空格字符外的普通字符必须与输入字符串严格匹配。

格式字符串中的空白意味着跳过下一个输入项前面的所有空白。

除了%c,其他转换说明都会自动跳过待输入值前面所有的空白。

如果把%c放在格式字符串中的空格前面,scanf()便会跳过空格,从第1个非空白字符开始读取。也就是说,scanf("%c", &ch)从输入中的第1个字符开始读取,而scanf(" %c", &ch)则从第1个非空白字符开始读取。

3.scanf()的返回值

scanf()函数返回成功读取的项数。如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,scanf()便返回0。当scanf()检测到“文件结尾”时,会返回EOF(EOF是stdio.h中定义的特殊值,通常用#define指令把EOF定义为-1)。

4.4.6 printf()和scanf()的*修饰符

在printf函数中,如果你不想预先指定字段宽度,希望通过程序来指定,那么可以用*修饰符代替字段宽度。

/* varwid.c -- 使用变宽输出字段 */
#include <stdio.h>
int main(void)
{
unsigned width, precision;
int number = 256;
double weight = 242.5;
printf("Enter a field width:\n");
scanf("%d", &width);
printf("The number is :%*d:\n", width, number);
printf("Now enter a width and a precision:\n");
scanf("%d %d", &width, &precision);
printf("Weight = %*.*f\n", width, precision, weight);
printf("Done!\n");
return 0;
}

scanf()中的用法与此不同。把放在%和转换字符之间时,会使得scanf()跳过相应的输出项。

/* skiptwo.c -- 跳过输入中的前两个整数 */
#include <stdio.h>
int main(void)
{
int n;
printf("Please enter three integers:\n");
scanf("%*d %*d %d", &n);
printf("The last integer was %d\n", n);
return 0;
}

4.4.7 printf()的用法提示

想把数据打印成列,指定固定字段宽度很有用。因为默认的字段宽度是待打印数字的宽度。

使用足够大的固定字段宽度可以让输出整齐美观。

在两个转换说明中间插入一个空白字符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟该数字一起输出(这样两个数字看起来像是一个数字)。这是因为格式字符串中的普通字符(包括空格)会被打印出来。

如果要在文字中嵌入一个数字,通常指定一个小于或等于该数字宽度的字段会比较方便。这样,输出数字的宽度正合适,没有不必要的空白。

4.5 关键概念

C语言用char类型表示单个字符,用字符串表示字符序列。字符通常用’'括起来,字符串通常用""括起来。字符串会以空字符/0结尾。

在程序中,最好用#define 定义数值常量,用 const 关键字声明的变量为只读变量。在程序中使用符号常量(明示常量),提高了程序的可读性和可维护性。

C 语言的标准输入函数(scanf())和标准输出函数(printf())都使用一种系统。在该系统中,第1个参数中的转换说明必须与后续参数中的值相匹配。

空白字符(制表符、空格和换行符)在 scanf()处理输入时起着至关重要的作用。除了%c 模式(读取下一个字符),scanf()在读取输入时会跳过非空白字符前的所有空白字符,然后一直读取字符,直至遇到空白字符或与正在读取字符不匹配的字符。

如果scanf()根据不同的转换说明读取相同的输入行时,如-13.45e12# 0,如果其对应的转换说是%d,scanf()会读取3个字符(-13)并停在小数点处,小数点将被留在输入中作为下一次输入的首字符。如果其对应的转换说明是%f,scanf()会读取-13.45e12,并停在#符号处,而#将被留在输入中作为下一次输入的首字符;然后,scanf()把读取的字符序列-13.45e12转换成相应的浮点值,并储存在float类型的目标变量中。如果其对应的转换说明是%s,scanf()会读取-13.45e12#,并停在空格处,空格将被留在输入中作为下一次输入的首字符;然后,scanf()把这 10个字符的字符码储存在目标字符数组中,并在末尾加上一个空字符。如果其对应的转换说明是%c,scanf()只会读取并储存第1个字符,该例中是一个空格 。

4.6 本章小结

字符串是一系列被视为一个处理单元的字符。在C语言中,字符串是以空字符(ASCII码是0)结尾的一系列字符。

字符串常量是用双引号括起来的字符序列。

scanf()函数(声明在string.h头文件中)可用于获得字符串的长度(末尾的空字符不计算在内)。

C预处理器为预处理器指令(以#符号开始)查找源代码程序,并在开始编译程序之前处理它们。处理器根据#include指令把另一个文件中的内容添加到该指令所在的位置。#define指令可以创建明示常量(符号常量),即代表常量的符号。limits.h和float.h头文件用#define定义了一组表示整型和浮点型不同属性的符号常量。另外,还可以使用const限定符创建定义后就不能修改的变量。

printf()和scanf()函数对输入和输出提供多种支持。两个函数都使用格式字符串,其中包含的转换说明表明待读取或待打印数据项的数量和类型。另外,可以使用转换说明控制输出的外观:字段宽度、小数位和字段内的布局。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值