接上一节:数组和指针完整实例详解
字符串在C语言中是常用的数据对象,却又是一个特殊的存在,本身并没有字符串类型,C语言的字符串实质是一个字符数组,它由一个个字符和结尾的空字符’\0’组成,另外字符串又和指针密切相关,字符数组名就是字符串的首地址。本文主要详细介绍C语言字符串的表示方式、字符串输入输出以及字符串相关的处理函数。
一、字符串声明首先介绍一下字符串字面量,例如1或2就是数字字面量,像number或count这些是变量,字符串字面量就是用双括号括起来的内容,例如“string”或“name”,字符串字面量属于静态存储类别,存储在静态内存区,字面量为const数据,其值可读不可写,使用双括号的字符串实质表示的是该字符串的首地址,也就是说”string”是该字符串的首地址。一个固定的字符串,它在静态内存区,在程序的任何地方取该字符串的地址都是相同的,看如下代码以及相应的图解:
// "hello"字符串字面量存储在静态区,其地址固定
char str_01[20] = "hello";
char *str_02 = "hello";
printf("str_01 address: %p\n", str_01);
// 输出:0028FE98
printf("str_02 address: %p\n", str_02);
// 输出:0040630C
printf("hello address: %p\n", "hello");
// 输出: 0040630C
printf("%d\n", str_02 == "hello");
// 输出:1
文章图片
1、数组方式表示字符串
数组方式表示字符串形如:char message[10] = “message‘,首先”message”是一个字符串字面量,保存在内存静态区中,是一个const数据,声明一个字符数组message,将字符串字面量”message”复制给栈区中的message数组变量,数组的长度至少比字符串长度多1。
所以这种方式是对原始字面量字符串的复制,其指针不能更改,也可以使用一个字符数组的形式,但是要在末尾加上一个空字符,在声明字符串中初始化可以略去[count]中的count让编译器自动计算大小。因为是对原始字符串的复制,所以相对于下面的指针方式效率不高,但是如果需要修改字符串则可以使用此方式,具体实例代码如下:
// 使用数组表示字符串
char str_01[4] = {'a', 'r', 'm', '\0'};
// 使用字符数组的形式
char str[10] = "arm";
// 将静态内存区中的"arm"复制给str
//str++;
// 数组方式的字符串不能更改字符串地址
char msg[] = "hello";
// 略去数组大小,让编译器自动计算字符串长度
puts(str_01);
puts(str);
printf("%p\n", str);
printf("%p\n", "arm");
printf("%p\n", msg);
2、指针方式表示字符串
指针方式和数组方式的区别就是,数组方式拷贝的是原始字符串字面量,而指针方式拷贝的是原始字符串的地址,所以使用指针方式相当于直接指向了静态区中的字符串,例如char *msg = ”msg“,指针msg指向的是原始字符串,因为msg是一个字符指针,所以它可以被重新赋值,具体代码如下:
// 使用指针方式表示字符串
char str_01[20] = "hello";
// 数组方式
char *str_02 = "hello";
char *msg = "200";
//str_02 = msg;
// 字符指针msg可以被重新赋值
//str_01 = msg;
// 但是数组形式的不可以
printf("str_01: %p\n", str_01);
// 输出:0028FE94
printf("str_02: %p\n", str_02);
// 输出:0040630C
printf("\"hello\": %p\n", "hello");
// 输出:0040630C,和str_02字符指针的地址相同,字符指针直接指向原始字符串
那么字符串数组中char *msg[]和char [][]又有什么区别?和上面提到的数组方式和指针方式的一样,前者直接指向原字符串字面量,后者复制原字符串。
二、字符串输入输出函数字符串输入输出函数如下:
1、getchar和putchar:自定义字符串输入输出可以使用getchar和putchar函数,这两个函数在前几节中已经介绍过。
2、scanf和printf:格式化输入输出,前几节已详细介绍。
3、gets和puts函数:其中gets函数读取所有输入直到换行符,会将换行符丢弃读入,字符串过长会导致缓冲区溢出,puts函数添加换行符输出。
4、gets_s函数,C11标准添加的函数,用于替换gets函数,仅从标准输入中读取数据,字符串过长丢弃超出字符串,丢弃换行符。
5、fgets和fputs,fgets读取所有字符,不会丢弃换行符。
其中要注意,接受字符串输入的变量需要已经分配空间,只有已经分配空间才能接受字符串,例如char *msg和char [],前者并未分配字符串空间,仅仅分配一个地址空间,后者已经分配空间。
函数的具体使用示例如下:
// 1、使用getchar和putchar
int ch;
ch = getchar();
putchar(ch);
putchar('\n');
// 2、使用scanf和printf
char message[20];
// message需要已经分配字符空间,使用char*message可以结合malloc
scanf("%s", message);
printf("%s\n", message);
// 3、使用gets和puts
char str[20];
gets(str);
puts(str);
// 添加换行符输出// 4、使用fgets和fputs
char *msg = (char*)malloc(sizeof(char) * 20);
fgets(msg, 20, stdin);
fputs(msg, stdout);
// 5、使用gets_s和puts
char title[20];
gets_s(title, 20);
// C11的可选函数
puts(title);
三、字符串处理函数对于字符串处理函数,最重要的是对前面内容的理解,否则有些函数可能不知道怎么用,在这些函数中,一些参数是const修饰的表明字符串不可更改,例如strcpy函数则是允许修改字符串,而对数组或字符串的处理函数的设计,一般至少需要一个字符串或数组,然后需要设计一个长度参数,因为根据一个数组参数还不能计算得到数组的长度,例如这种形式的数组char *str,所以在使用C语言函数也要习惯一下C这种风格,这处理函数的头文件在stdlib.h和string.h中。
1、基本字符串处理函数
(1) sprintf格式化打印字符串,这个函数可以将其它类型的数据转换成字符串,是一个很有用的函数。
(2) strlen,获取字符串长度。
(3)strcat,字符串连接
(4) strcmp,比较字符串
(5)strncmp,比较字符串前n个字符
(6) strcpy,复制字符串
(7)strncpy,复制前n个字符
(8)strchr,查找字符,返回第一个出现字符的位置。
2、字符串转换函数
(1) atof,将字符串转为float。
(2) atoi,将字符串转为int。
(3) atol,将字符串转为long。
(4) strtod,将字符串转为double,base参数表示进制,例如2进制、10进制、16进制。 另外,在ctype.h头文件中有相关的字符测试函数,例如isalpha,isalnum等,具体的函数使用说明可以参考Linux C函数参考文档:
(Linux C函数参考文档CHM下载:
链接: https://pan.baidu.com/s/16cqfnSMiRNBn5peRpiqwMw
提取码: r72s
【C语言简明教程(十三)(字符串和字符串处理函数实例详解)】)
推荐阅读
- ES6中的iterable数组遍历用法及详解
- JavaScript中如何通过键值快速查元素(Map和Set数据类型)
- 使用vue+uni-app开发天猫商城案例
- C语言简明教程(十二)(数组和指针完整实例详解)
- 微信web开发者工具启动不了打不开——已解决
- layui.flow流加载图标和样式的修改案例
- uni-app vue框架组件添加使用及注意事项
- C语言简明教程(十一)(函数和指针)
- 游戏介绍 – XCOM(Chimera Squad)