跳到主要内容

字符

在C语言中定义一个字符很容易:

char str = 'a';

通过 char 关键字可以定义一个字符类型变量。需要注意的是在给字符变量赋值时,应该使用单引号来包裹住这个字符(用双引号在DevC++中会出现警告,最好使用单引号)。输出这个字符时,使用 %c 来进行接收:

printf("%c",str);       // a

当然,对一个字符类型赋值为一个整数也是可以的,系统会自己进行转换,比如:

char str = 66;
printf("%c",str); // B

运行会输出大写字母 B,在 ASCII 表中,第66编号字符对应的就是 B,这样的操作在第一篇以经说过。需要注意的是,当你给 str 变量赋一个浮点型变量时,它会截取小数部分,用整数部分去对应 ASCII 码表。

getchar(void);putchar(char);函数

这两个函数一个可以传参一个不可以;使用这两个函数只需<stdio.h>库,getchar() 函数需要一个字符(不是字符串)变量来接收,该函数功能是让输入一个字符,并把输入的这个字符赋给接收的那个变量。
putchar() 函数需要传入一个字符变量,用来把这个字符变量打印到控制板上,他还能赋给一个变量,这个变量会接受传入参数的值:

char str = getchar();
int b = putchar(str);
printf("\n char b = %c\n",b); // 类型转换
// 你也可以直接这样: putchar(b);

运行后,如果你输入一个字符 a 则会打印出两个 a。

字符类数组

定义字符类数组也很容易:

char str[2] = {'a','b'};
for(int i = 0;i < 2;i ++){
printf("%c\t",str[i]); // a b
}

比如我们写个程序,这个程序要我们给一个数组的成员赋成对用 26 个大写字母,我们可以这么做:(大写字母A从65开始的)

char str[26] = {0};
int num = 26 + 65;
for(int i = 65;i < num;i ++){
str[i] = i;
printf("%c\t",str[i]);
}

字符串类型

在C语言中想要操作字符串,最好引入有关字符及字符串操作的库 —— <string.h> 字符串库中提供了许多方便操作字符及字符串的函数,引入库后我们可以直接调用里面的库函数。
先来看看怎么定义一个字符串。定义一个字符串和数组很像,也是 变量名[下标数字] = 'xxx' 的形式。有所不同的是:在字符串中的下标是我们开辟的空间大小。在第一篇中,我们已经说过,一个字符占一个字节大小:

printf("%d\n",sizeof(char));    // 1

因此,我们下标是几也就是最多能给这个字符串赋几个连续的字符。比如:指定一个字符串变量为 char str[3] 则我们赋值时最多只能赋一个最多有三个字符的字符串,超出会警告。
在赋值操作时,字符串不应该用单引号包裹,而应换成双引号。应记住:

  • 字符变量赋值用单引号
  • 字符串变量赋值用双引号

在不适应字符操作库函数时我们可以不用引入 <string.h> 库。一个字符串完整的定义:

char str[2] = "ab";

变量字符串

遍历字符串与遍历数组一样:

char str[3] = "abc";
for(int i = 0;i < 3;i ++){
printf("%c\t",str[i]);
// 注意这里用 %c
}

运行会输出:a b c
当然,对一个字符串声明后直接赋值可以不用去指定下标数字,比如:

char str[] = "abcd";

一个汉字的字节长度

一个汉字的字节长度是2。看下面代码:

char str[] = "我";
printf("%d\n",sizeof(str));

运行上面代码后,却发现结果却是 3!这是为什么呢?这是因为在一个字符串中通常会有一个结束字符 —— '\0' 。这是系统自动分配的。用以表示一个字符串结束的标志。这个字符对操作字符串是很有用的,特别是遍历一个字符串。为了验证有这个字符,可以这么干:

char str[] = "qwer";
if(str[sizeof(str)] == '\0'){
printf("Hahaha!");
}

运行后,会发现打印出了字符串 Hahaha!。那么这个字符有什么用呢?
字符串的存储方式和数组是一样的,每个元素的存储单元是相邻的。就如同一列盘子,一个元素相当于一个盘子,盘子与盘子之间是相邻的(这个盘子下面又是一个盘子)。这在指针那一篇会有更详细的介绍。我们在不知道一个字符串有多少字节的情况下通过 '\0' 来遍历一个字符串:

char str[] = "123qwe";
for(int i = 0;str[i] != '\0';i ++){
printf("%c\t",str[i]);
}

注意代码中的 str[i] != '\0' ,这样就做到了遍历一个不确定长度的字符转。

请注意if语句或 for 循环中条件的字符 —— =='\0' 这里用了单引号,在这里面也最好用单引号,用双引号很可能会出现警告。

说到这里,再看一个例子,在这个例子中,我们想要输出汉字,这该怎么做呢?看一下代码:

char str[] = "你好";
for(int i = 0;str[i] != '\0';i ++){
printf("%c\t",str[i]);
}

运行后发现并不是我们想要的结果,因为输出函数输出的是 str[i] ,这是一个单字节字符,而汉字是双字节字符,因此没有达到我们想要的结果。那么应该怎么完好的输出想要的汉字呢?
有两种办法:

  1. 使用 %s 直接输出整个字符串;
  2. 把单个汉字存入数组中,遍历数组,再用 %s 方式输出单个汉字

不用以上两种办法,一般输出都会乱码。 第一种:

char str = "你好!";
printf("%s\n",str);

第二种方法:

int main(){
char str[][10] = { // 这里也可以是 str[3][10];
// 对多维数组进行直接赋值时行数可以不明确指定
{"你"},
{"好"},
{"!"}
};
for(int i = 0;i < 3;i ++){
printf("%s\t",str[i]);
// 这里你也可以使用指针: *(str+i)
}
return 0;
}

在上面代码中,声明了一个包裹字符串的数组(一个三行不知道多少列的数组),因为汉字不清楚占多少"列",因此我给他分了10个字节的空间(以防溢出),当然你也可以变个数字;打印时,我们访问每一行,并用%s 来打印出汉字。

gets() 函数和 puts() 函数

gets() 函数和 puts() 函数是C语言中 <stdio.h> 中的函数,前者是通过传入一个字符串变量,来给这个变量进行赋值,后者是输出一个字符串:

char str[20];
gets(str); // 或者 scanf("%s",&str);
printf("%s\n",str); // 或者 puts(str);

因此,你可以用gets()函数来代替 scanf()函数,用puts() 函数来代替 printf()函数

C语言字符操作库 —— <string.h>

注意:在使用库函数之前,应先引入库:#include <string.h>

几个常用的字符操作函数:

  • strlen(str); —— 返回一个字符串的长度
  • strcat(str1,str2); —— 将两个字符串拼接成一个字符串
  • strcmp(str1,str2); —— 比较两个字符串
  • strcpy(str2,str1); —— 将str1拷贝到str2字符串中,并返回str2