1、C语言没有专门用于存储字符串的变量类型,字符串都被存储在char类型的数组中。数组由连续的存储单元组成,字符串中的字符被存储在相邻的存储单元中,每个单元存储一个字符。
注:数组末尾位置的字符\0。是空字符(null字符)C语言用它来标记字符串的结束。C语言中的字符串一定以空字符结束,所以数组的容量必须至少比待存储字符串中的字符数多1。
2、声明创建数组
e.g. char square[30];
注:字符串的创建,首先要创建一个数组,把字符串中的字符逐个放入数组,还要记得在末尾加上一个\0。
3、使用字符串
#include
#define PART "Nice to meet you."
int main(void)
{
char name[40];
printf("What's you name?");
scanf("%s",name);
printf("Hello, %s. %s\n",name,PART);
return 0;
}
注:1、打印字符串要在printf()函数里面用%s。
2、scanf()函数在读取字符串时,在遇到第一个空格时就会停止读取。
3、fgets()函数,用于读取一般字符串。
attention:字符串与字符区别
字符串常量"X"是char 数组;实际上由两个字符组成:'X'和空字符\0;
字符常量'X'是char类型。
4、strlen()函数
strlen()和sizeof()一样用%zd这个转换说明。
strlen()可以准确给出字符大小,而sizeof()则会将整个数组的大小输出。
注:sizeof何时用圆括号?当运算对象是类型时,必须加圆括号;当是特定量时,圆括号可有可无。
5、常量和C预处理器
C预处理器也可以用来定义常量。如:#define TAXRATE 0.015 --明示常量
注:符号常量命名规则,可以使用大小写字母、数字、下划线字符,首字符不能为数字。
C预处理器还可以定义字符和字符串常量。前者使用单引号,后者使用双引号。
如:#define BEEP '\a'
#define OP "The scenes are so wonderful."
6.const 限定符
const关键字,用于限定一个变量为只读。
如:const int MOON = 15; // 在程序中不可以更改,值为15。
一、格式化输出
转换说明
转换说明 |
输 出 |
%a |
浮点数、十六进制数字和p-记数法 (C99) |
%A |
浮点数、十六进制数字和P-记数法 (C99) |
%c |
一个字符 |
%d |
有符号十进制整数 |
%e |
浮点数、e-记数法 |
%E |
浮点数、E-记数法 |
%f |
浮点数,十进制记数法 |
%g |
根据数值不同自动选择%f或者%e。%e格式在指数小于-4或者大于等于精度时使用 |
%G |
根据数值不同自动选择%f或者%E。%E格式在指数小于-4或者大于等于精度时使用 |
%i |
有符号十进制整数 (与%d相同) |
%o |
无符号八进制整数 |
%p |
指针(就是指地址) |
%s |
字符串 |
%u |
无符号十进制整数 |
%x |
使用十六进制数字0f 的无符号十六进制整数 |
%X |
使用十六进制数字0F的无符号十六进制整数 |
%% |
打印一个百分号 |
printf() 修饰符
修饰符 |
意 义 |
标志 |
五种标志 (-、+、空格、# 和0) 都将在表三中描述,可以使用零个或多个标志 |
digit(s) |
字段宽度的最小值。如果该字段不能容纳要打印的数或者字符串,系统会使用更宽的字段。示例:“%4d” |
.digit(s) |
精度。对于%e、%E和%f转换,是将要在小数点的右边打印的数字的位数。对于%g和%G转换,是有效数字的最大位数。对于%s转换,是将要打印的字符的最大数目。对于整数转换,是将要打印的数字的最小位数;如果必要,要使用前导零来达到这个位数。只使用“.”表示其后跟随一个零,所以%.f与%.0f相同。示例:“%5.2f”打印一个浮点数,他的字段宽度为5个字符,小数点后有两个数字。 |
h |
和整数转换说明符一起使用,表示一个short int 或者 unsigned short int 类型数值。 示例:“%hu”、“%hx”和“%6.4hd” |
hh |
和整数转换说明符一起使用,表示一个signed char 或者unsigned char类型数值。 示例:“%hhu”、“%hhx”和“%6.4hhd” |
j |
和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值。 示例:“%jd”和“%8jX” |
l |
和整数说明符一起使用,表示一个long int 或者unsigned long int 类型值。 示例:“%ld”和“%8lu” |
ll |
和整数说明符一起使用,表示一个long long int或 unsigned long long int 类型值 (C99)。 示例:“%lld”和“%8llu” |
L |
和浮点转换说明符一起使用,表示一个long double值。 示例:“%Lf”和“%10.4Le” |
t |
和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差相对应的类型) (C99) 示例:“%td”和“%12ti” |
z |
和整数转换说明符一起使用,表示一个size_t值(sizeof返回的类型) (C99)。 示例:“%zd”和“%12zx” |
printf()的标志
修饰符 |
意 义 |
- |
项目是左对齐的,也就是说,会把项目打印在字段的左侧开始处。示例:“%-20s” |
+ |
有符号的值若为正,则显示带加号的符号;若为负,则带减号的符号。示例:“%+6.2f” |
(空格) |
有符号的值若为正,则显示时带前导空格(但是不显示符号);若为负,则带减号符号。+标志会覆盖空格标志。示例:“% 6.2f” |
# |
使用转换说明的可选形式。若为%o格式,则以0开始;若为%x和%X格式,则以0x或0X开始,对于所有的浮点形式,#保证了即使不限任何数字,也打印一个小数点字符。对于%g和%G格式,它防止尾随零被删除。示例:“%#o”、“%#8.0f”和“%+#10.3E” |
0 |
对于所有的数字格式,用前导零而不是用空格填充字段宽度。如果出现-标志或者指定了精度(对于整数)则忽略该标志。示例:“%010d”和“%08.3f” |
e.g.
#include
#define PART 959
int main(void)
{
printf("*%d*\n",PART);
printf("*%2d*\n",PART);
printf("*%10d*\n",PART);
printf("*%-10d*\n",PART);
return 0;
}
运行结果:
*959*
*959*
* 959*
*959 *
注:第二个打印输出的是两个字符宽度,但是待打印的整数有三位数字,所以字符宽度会自动扩大以符合整数的长度。
#include
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**
注:如果0标记和精度一起出现,0标记会被忽略。
#include
#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 ]
practice:1、
#include
int main(void)
{
char name[40];
scanf("%s",name);
printf("The %s family just may be %c%6.2f euros richer!",name,'€',666.666666);
return 0;
}
4、printf()的返回值
返回值可以赋给变量,也可以用于计算,还可以作为参数传递。
printf()函数的返回值是打印字符的个数(包括空格和换行符\n)
5、打印较长的字符串(给字符串断行)
three ways
#include
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"); //第三种方法
return 0;
}
6、printf()中的*修饰符
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;
}
变量width提供了字段宽度,number是待打印的数字。(两个变量有位置顺序)
7、printf()的用法提示
(1)、使用足够大的固定字段宽度可以让输出整齐美观。
(2)、两个转换说明中间插入一个空白字符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟该数字一起输出。
(3)、若要在文字中嵌入一个数字,通常指定一个小于或等于该数字宽度的字段会比较方便。
二、格式化输入
(一)、scanf()函数用法两条规则:1、若用scanf()读取基本变量类型的值,要在变量名前加上一个&;
2、若用scanf()把字符串读入字符数组中,不要使用&。
e.g.char name [40];
scanf("%s",name);
注:scanf()用空白把输入分成多个字段。
(二)、scanf()读取输入规则
除了%c,其他的转换说明都会自动跳过待输入值前面所有的空白。故scanf("%d%d",&n,&m)与scanf("%d %d",&n,&m)一样。
对于%c,scanf("%c",&m)从输入的第一个字符开始读取,而scanf(" %c",&m)则会从第一个非空白字符开始读取。
scanf()的转换说明符
转换说明符 |
意 义 |
%c |
把输入解释成一个字符 |
%d |
把输入解释成一个有符号十进制整数 |
%e,%f,%g, %a |
把输入解释成一个浮点数 (%a是C99标准) |
%E,%F,%G,%A |
把输入解释成一个浮点数 (%A是C99标准) |
%i |
把输入解释成一个有符号十进制整数 |
%o |
把输入解释成一个有符号八进制数 |
%p |
把输入解释成一个指针(地址) |
%s |
把输入解释成一个字符串;输入的内容以一个非空白字符作为开始,并且包含知道下一个空白字符的全部字符 |
%u |
把输入解释成一个无符号十进制整数 |
%x,%X |
把输入解释成一个有符号十六进制整数 |
scanf()的转换修饰符
修饰符 |
意 义 |
* |
滞后赋值。示例:“%*d” |
digit(s) |
最大字段宽度;在达到最大字段宽度或者遇到第一个空白字符时(不管哪一个先发生都一样)停止对输入项的读取。示例:“%10s” |
hh |
把整数读作signed char 或 unsigned char 。示例:“%hhd”“%hhu” |
ll |
把整数读作long long或者 unsigned long long (C99)。示例:“%lld”“%llu” |
h,l或L |
“%hd”和“hi”指示该值将会存储在一个short int中。 “%ho”“%hx”和“%hu”指示该值将会存储在一个unsigned short int中。 “%ld”和“%li”指示该值将会存储在一个long中。 “%lo”“%lx”和“%lu”指示该值将会存储在一个unsigned long中。 “%le”“%lf”和“%lg”指示该值以double类型存储。将L(而非l)与e、f和g一起使用指示该值以long double类型存储。 如果没有这些修饰符,d、i、o和x指示int类型,而e、f和g指示float类型。 |
二、scanf()函数的返回值
scanf()函数返回成功读取的项数。若需读取一个数字,但输入的是一个非数字字符串,则返回0。
三、scanf()的*修饰符
与printf()的*修饰符不同。scanf的*功能是跳过。
e.g.
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;
}
运行结果:
Please enter three integers:
2000 2001 2002
The last integer was 2002
原理:跳过两个整数,把第三个整数拷贝给n。