C语言: 字符数组与字符串总结

举报
DS小龙哥 发表于 2022/02/27 12:37:16 2022/02/27
【摘要】 字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。

字符数组与字符串

用来存放字符的数组称为字符数组,例如:

char a[10];    //一维字符数组
char b[5][10];  //二维字符数组
char c[20]={'c', '  ', 'a', 'b', 'c', 'd', 'e', 'f','g'};  // 给部分数组元素赋值
char d[]={'c', ' ', 'a', 'b', 'c', 'd', 'e', 'f','g' };  //对全体元素赋值时可以省去长度

字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。
C语言规定,可以将字符串直接赋值给字符数组,例如:

char str[30] = {"1234567890"};
char str[30] = "1234567890";  //这种形式更加简洁,实际开发中常用

数组第0个元素为 ‘1’,第1个元素为 ‘2’,第2个元素为 ‘3’,后面的元素以此类推。也可以不指定数组长度,例如:

char str[] = {"1234567890"};
char str[] = "1234567890";  //这种形式更加简洁,实际开发中常用

在C语言中,字符串总是以’\0’作为串的结束符。上面的两个字符串,编译器已经在末尾自动添加了’\0’。

'\0’是ASCII码表中的第0个字符,用NUL表示,称为空字符。该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅作为字符串的结束标志。

puts 和 printf 在输出字符串时会逐个扫描字符,直到遇见 ‘\0’ 才结束输出。

请看下面的例子:

#include <stdio.h>
int main(){
    int i;
    char str1[30] = "1234567890";
    char str2[] = "1234567890";
    char str3[30] = "1234567890 \0 123";
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    printf("str3: %s\n", str3);
    return 0;
}

运行结果:

str1: 1234567890
str2: 1234567890
str3: 1234567890

str1 和 str2 很好理解,编译器会在字符串最后自动添加 ‘\0’,并且数组足够大,所以会输出整个字符串。对于 str3,由于字符串中间存在 ‘\0’,printf() 扫描到这里就认为字符串结束了,所以不会输出后面的内容。

需要注意的是,用字符串给字符数组赋值时由于要添加结束符 ‘\0’,数组的长度要比字符串的长度(字符串长度不包括 ‘\0’)大1。

例如:

char str[] = "C program";

该数组在内存中的实际存放情况为:字符串长度为 9,数组长度为 10。

C语言字符串处理函数

C语言提供了丰富的字符串处理函数,例如:字符串的输入、输出、合并、修改、比较、转换、复制、搜索等,使用这些现成的函数可大大减轻编程的负担。

用于输入输出的字符串函数,例如printf、puts、scanf、gets等,使用时应包含头文件stdio.h,使用其它字符串函数则应包含头文件string.h。

字符串长度函数strlen

strlen 是 string length 的缩写,用来获得字符串的长度。所谓长度,就是包含多少个字符(不包括字符串结束标志 ‘\0’)。

语法格式为:

strlen(arrayName);
strlen 将返回字符串的长度,它是一个整数。
请看下面的例子:
#include <stdio.h>
#include <string.h>
int main(){
    char str[]="C language";
    int len = strlen(str);
    printf("The lenth of the string is %d\n", len);
    return 0;
}
运行结果:
The lenth of the string is 10
需要说明的是,strlen 会从字符串的第 0 个字符开始计算,直到遇到字符串结束标志 '\0'

将上面代码中的 str 改为:

char str[]="C \0language";

那么输出结果就是:

The lenth of the string is 2

字符串连接函数 strcat。

strcat是 string catenate 的缩写,意思是把两个字符串拼接在一起,语法格式为:
strcat(arrayName1, arrayName2);

arrayName1、arrayName2 为需要拼接的字符串。
strcat 将把 arrayName2 连接到 arrayName1 后面,并删去 arrayName1 最后的结束标志 ‘\0’。这就意味着,arrayName1 的长度要足够,必须能够同时容纳 arrayName1 和 arrayName2,否则会越界。
strcat 返回值为 arrayName1 的首地址。

请看下面的例子:

#include <stdio.h>
#include <string.h>
int main(){
    char str1[40]="My name is ";
    char str2[20];
    printf("Input your name:");
    gets(str2);
    strcat(str1,str2);
    puts(str1);
    return 0;
}
运行结果:
Input your name:xiao p
My name is xiao p

字符串复制函数strcpy

strcpy 是 string copy 的缩写,意思是字符串复制,语法格式为:

strcpy(arrayName1, arrayName2);

strcpy 会把 arrayName2 中的字符串拷贝到 arrayName1 中,字符串结束标志 ‘\0’ 也一同拷贝。

请看下面的例子:
#include <stdio.h>
#include <string.h>
int main(){
    char str1[15], str2[]="C Language";
    strcpy(str1, str2);
    puts(str1);
    printf("\n");
    return 0;
}
运行结果:
C Language

strcat 要求 arrayName1 要有足够的长度,否则不能全部装入所拷贝的字符串。

字符串比较函数strcmp

strcmp 是 string compare 的缩写,意思是字符串比较,语法格式为:strcmp(arrayName1, arrayName2);

arrayName1 和 arrayName2 是需要比较的两个字符串。

字符本身没有大小之分,strcmp() 以各个字符对应的 ASCII 码值进行比较。strcmp() 从两个字符串的第 0 个字符开始比较,如果它们相等,就继续比较下一个字符,直到遇见不同的字符,或者到字符串的末尾。

返回值:若 arrayName1 和 arrayName2 相同,则返回0;若 arrayName1 大于 arrayName2,则返回大于 0 的值;若 arrayName1 小于 arrayName2,则返回小于0 的值。

示例:对4组字符串进行比较

#include <stdio.h>
#include <string.h>
int main(){
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    char *c = "aacdef";
    char *d = "aBcDeF";
    printf("strcmp(a, b) : %d\n", strcmp(a, b));
    printf("strcmp(a, c) : %d\n", strcmp(a, c));
    printf("strcmp(a, d) : %d\n", strcmp(a, d));
    return 0;
}
运行结果:
strcmp(a, b) : 1
strcmp(a, c) : -1
strcmp(a, d) : 0

C语言字符串的输入输出

字符串的输出

在C语言中,输出字符串的函数有两个:

int puts(const char *s);
int printf(const char *format, ...);

puts():直接输出字符串,并且只能输出字符串。

printf():通过格式控制符 %s 输出字符串。除了字符串,printf() 还能输出其他类型的数据。

实例:

#include <stdio.h>
int main(){
    int i;
    char str[] = "1234567890";
    printf("%s\n", str);  //通过变量输出
    printf("%s\n", "1234567890");  //直接输出
    puts(str);  //通过变量输出
    puts("1234567890");  //直接输出
    return 0;
}
运行结果:
1234567890
1234567890
1234567890
1234567890

在printf() 函数中使用%s输出字符串时,在变量列表中给出数组名即可,不能写为printf("%s", str[]);。

字符串的输入

在C语言中,输入字符串的函数有两个:

char *gets(char *s);
int scanf(const char *format, ...);

scanf():通过格式控制符 %s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。

gets():直接输入字符串,并且只能输入字符串。

(1)使用 scanf() 读取字符串

#include <stdio.h>
int main(){
    char str1[30], str2[30];
    printf("Input str1: ");
    scanf("%s", str1);
    printf("Input str2: ");
    scanf("%s", str2);
    printf("str1: %s\nstr2: %s\n", str1, str2);
    return 0;
}

由于字符数组长度为30,因此输入的字符串长度必须小于30,以留出一个字节用于存放字符串结束标志\0

前面讲scanf 函数时讲到,从键盘上读取数据时,各个变量前面要加取地址符&,用以获得变量的地址。

例如:

int a, b;
scanf("%d %d", &a, &b);

但是在本节的示例中,将字符串读入字符数组却没有使用&。

例如:

char str1[20], str2[20], str3[20], str4[20];
scanf("%s %s %s %s",str1, str2, str3, str4);

这是因为C语言规定,数组名就代表了该数组的地址。整个数组是一块连续的内存单元,如有字符数组char c[10].

C语言还规定,数组名所代表的地址为第0个元素的地址,例如char c[10];,c就代表c[0]的地址。第0个元素的地址就是数组的起始地址,称为首地址。也就是说,数组名表示数组的首地址。

C语言数组续-----

设数组c的首地址为0X2000,也即c[0]地址为0X2000,则数组名c就代表这个地址。因为c已经表示地址,所以在c前面不能再加取地址符&,例如写作scanf("%s",&c);是错误的。
有了首地址,有了字符串结束符’\0’,就可以在内存中完整定位一个字符串了。

例如:

printf("%s", c);

printf 函数会根据数组名找到c的首地址,然后逐个输出数组中各个字符直到遇到 ‘\0’ 为止。

int、float、char 类型的变量表示数据本身,数据就保存在变量中;而数组名表示的是数组的首地址,数组保存在其他内存单元,数组名保存的是这块内存的首地址。

(2) 使用 gets() 读取字符串

char *gets(char *s);

gets 是 get string 的缩写,意思是获取用户从键盘输入的字符串。

语法格式为:gets(arrayName);

arrayName 为字符数组。从键盘获得的字符串,将保存在 arrayName 中。
实例:

#include <stdio.h>
int main(){
    char str1[30], str2[30];
    printf("Input str1: ");
    gets(str1);
    printf("Input str2: ");
    gets(str2);
    printf("str1: %s\nstr2: %s\n", str1, str2);
    return 0;
}

gets() 函数不会把空格作为输入结束的标志,而只把回车换行作为输入结束的标志,这与 scanf() 函数是不同的。

总结:如果希望读取的字符串中不包含空格,那么使用 scanf() 函数;如果希望获取整行字符串,那么使用 gets() 函数,它能避免空格的截断。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。