目录
第四章 字符串与格式化输入输出
字符串简介
1.char类型数组与null字符
C语言没有用于专门存储字符串的变量类型,字符串都被存储在char类型的数组中。数组由连续的存储单元组成,字符串中的字符被存储在相邻的存储单元中,每个单元存储一个字符。
2.字符串与字符
字符串常量"x"
与字符常量'x'
不同,前者是派生类型(char
数组),后者是基本类型(char
)。字符串常量"x"
由两个字符'x'
和空字符\0
组成。
3.strlen()函数
对于一个字符串使用strlen()
函数,可以得到它存储的字符串长度(不需要加上末尾的空字符)。使用sizeof()
指的是给char
数组分配的存储空间。
字符串长度
常量和C预处理器
1.C语言声明常量
#define TAXRATE 0.015
2.定义字符和字符串常量
字符使用单引号,字符串使用双引号
#define BEEP '\a'
#define TEE 'T'
#define ESC '\033'
#define OOPS "Now you have done it!"
注意#define TOES = 20
是错误的,相当于预处理器会把所有TOES
都替换为= 20
而非20
。
3.const限定符
用于限定一个变量为只读,改变量的值在整个程序中不可更改
const
限定符用起来比#define
更灵活,后续讨论。
4.明示变量
在
limits.h
和float.h
中分别提供了与整数类型和浮点类型大小限制相关的详细信息,每个头文件中都定义了一系列供实现使用的明示变量。
举个例子,limits.h
中包含以下类似的代码,用于表示int
型可表示的最大值和最小值。
#define INT_MAX +32767
#define INT_MIN -32768
printf()和scanf()
这两个函数实现了程序和用户之间的交流,称为输入/输出函数。
1.printf()函数
如果需要打印%
的话,只需要使用%%
。
printf()中可以插入转换说明,比如%c
输出单个字符,%d
输出有符号十进制整数,%s
输出字符串等。
同时printf()函数在%
和转换字符之间可以插入转换说明修饰符。
修饰符 | 含义 |
---|---|
标记 | 包含- 、+ 、# 、空格和0 五种标记,可以不使用或使用多个 |
数字 | 最小字段宽度 |
.数字 | 精度 |
h | 和整型转换说明一起使用,表示short int 或unsigned short int |
hh | 表示signed char 或unsigned char |
j | 表示intmax_t 或uintmax_t |
l | 表示long int 或unsigned long int |
ll | 表示long long int 或unsigned long long int |
L | 表示long double |
t | 表示ptrdiff_t |
z | 表示size_t |
sizeof
运算符会返回以字节为单位的类型或值的大小,这应该是某种形式的整数。但是标准中只规定了该值是无符号整数,在不同的实现中,它可能是各种各样的整数。为了实现不同系统更好的移植性,C语言在stddef.h
头文件中已经把size_t
定义为系统使用sizeof
返回的类型。
float参数的转换
在printf()
函数中对于浮点类型有double
和long double
的转换说明,但是没有float
类型的。这是因为printf()
函数会将所有float
类型的参数自动转换为double
类型,实现对不同标准的兼容。
标记 | 含义 |
---|---|
- | 待打印项左对齐,配合宽度一起使用 |
+ | 有符号值若为正,则在值前面显示+ 号,如果为负,则显示- 号 |
空格 | 有符号值若为正,则在值前面显示前导空格(不显示任何符号);若为负,则在值前面显示- 号 |
# | 把结果转换为另一种形式 |
0 | 对于数值格式,用前导0代替空格填充字段宽度。对于整数格式,如果出现- 标记或者指定精度,则忽略该标记 |
2.使用修饰符和标记的例子
控制整数的输出格式:
#include<stdio.h>
#define PAGES 959
int main(void)
{
printf("*%d*\n", PAGES);
//由于限制的宽度2小于PAGES本身长度,所以相当于不做限制
printf("*%2d*\n", PAGES);
printf("*%10d*\n", PAGES);
printf("%-10d*\n", PAGES);
return 0;
}
输出结果:
*959*
*959*
* 959*
959 *
控制浮点数的输出格式:
#include<stdio.h>
int main(void)
{
const double RENT = 3852.99;
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*
3.scanf()函数
scanf()
函数所做的工作和printf()
所做的工作正好相反,scanf()
把输入的字符串转换为整数、浮点数、字符或字符串等。但是scanf()
函数需要使用指向变量的指针。
- 如果用
scanf()
读取基本变量类型的值,在变量名前加上一个&
- 如果用
scanf()
把字符串读入字符数组中,不需要使用&
对于
scanf()
,除了%c
之外的所有转换说明都会自动跳过待输入值前面的所有空白
scanf()
函数返回成功读取的项数。
- 如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,
scanf()
便返回0。 - 当
scanf()
检测到“文件结尾”时,会返回EOF
(一般会使用#define
指令将EOF
定义为-1)。
4.printf()的用法提示
- 如果想要将数据打印成列,那么指定足够大的固定字段宽度可以让输出整齐美观
- 如果两个转换说明中间插入一个空白符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟着该数字一起输出