C语言的字符串大串讲
前言在走进的代码世界之前,先领略一下小桥流水美景的诗意世界吧
完了就直接进入正题
一、C语言字符串的手动内存管理1、C语言无字符串代码语言:javascript复制"hello bit.\n"这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
2、'\0’的重要性代码语言:javascript复制#include
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
char arr1[] = "Hello";
char arr2[] = { 'H', 'e', 'l', 'l', 'o' };
char arr3[] = { 'H', 'e', 'l', 'l', 'o', '\0'};
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}在这里插入图片描述
在上面的代码运行结果可以看到,我们在输出arr2时出现了乱码形式
思考:为什么会出现这种情况呢?
因为在arr2中并不包含字符串的结束标志即’\0’,所以会出现上面的乱码!
字符串与\0的深度解析 当我们用printf()函数以字符串形式进行输出时,只有遇到’\0’才会停止输出
这时候肯定会有码友会问:为什么输出arr1就不会产生乱码?
因为在 “” 里面的字符串中就已经自动包含了字符串的结束标志即’\0’,所以当我们输出arr1自然就不会产生乱码
当我们在使用 {} 字符串的定义的方式时,一定要记得加上字符串的结束标志,否则就会出现乱码现象
小编提醒:一个合格的程序员必备的素养,是对代码的每一处细节严格把控,虽然我们有时候用不到,但这却是我们必须要做的
3、字符串的初始化方式
示例
说明
直接赋值
char s[] = "abc";
自动计算长度并补 '\0'(长度=4)
指定大小
char s[5] = "abc";
剩余空间填充 '\0'(实际存储 a b c \0 \0)
逐个字符
char s[4] = {'a','b','c','\0'};
必须显式添加 '\0',否则不是合法字符串
指针
char *s = "abc";
指向只读的字符串常量(不可修改内容)
4、与字符串相关的格式说明符在 C 语言中,与字符串相关的格式说明符主要用于输入/输出函数
(1)%s用途:输入/输出 字符串(以 ‘\0’ 结尾的 char 数组或指针)。
代码示例:
代码语言:javascript复制char str[] = "Hello";
printf("%s\n", str); // 输出字符串
scanf("%s", str); // 输入字符串(遇空格停止)注意:
scanf(“%s”, str) 不安全(可能缓冲区溢出),推荐:代码语言:javascript复制scanf("%19s", str); // 限制最大长度(数组大小-1)或使用 fgets:代码语言:javascript复制fgets(str, sizeof(str), stdin); // 更安全(读取一行)(2)%c用途:输入/输出 单个字符(char 类型)。
代码示例:
代码语言:javascript复制char ch = 'A';
printf("%c\n", ch); // 输出字符 'A'
scanf("%c", &ch); // 输入单个字符(包括空格/换行)注意:
若需跳过空白字符,加空格:
代码语言:javascript复制scanf(" %c", &ch); // 忽略前面的空格/换行(3)%p用途:输出 指针的地址(十六进制格式)。
代码示例:
代码语言:javascript复制char *ptr = "Hello";
printf("%p\n", (void *)ptr); // 输出指针地址(如 0x55a1b2c3d4e5)后面我们讲到指针的时候会深度解析
拓展:fgetsfgets 是 C 语言标准库中用于安全读取字符串的重要函数,相比 gets 和 scanf 的 %s,它提供了更好的安全性和控制能力。
最简单的 fgets 使用模板代码语言:javascript复制#include
int main() {
char buffer[100]; // 定义一个足够大的字符数组
printf("请输入内容: ");
fgets(buffer, sizeof(buffer), stdin); // 读取输入
printf("你输入的是: %s", buffer);
return 0;
}z关键要点 三个必要参数:
buffer:存储输入的字符数组
sizeof(buffer):最大读取长度(自动计算数组大小)
stdin:表示从标准输入(键盘)读取
自动添加结束符:
fgets 会自动在字符串末尾添加 \0
所以实际读取的字符数 = 指定长度 - 1
拓展:使用fgets的时候,如何去掉换行符
如果用户按了回车,换行符 \n 会被包含在字符串中
示例:输入 “hello” 后按回车,buffer 内容为 “hello\n\0”
这时候我们可以用到头文件
头文件
代码语言:javascript复制#include
#include
int main() {
char buffer[100];
printf("请输入: ");
fgets(buffer, sizeof(buffer), stdin);
// 去除换行符
buffer[strcspn(buffer, "\n")] = '\0';
printf("处理后的输入: %s", buffer);
return 0;
}(4)其它相关的格式说明符 下面这些说明符虽然功能强大,但是很少被使用,这里我们只是作简单的讲解,感兴趣的朋友可以去了解一下
1. %[…](扫描集)用途:自定义 scanf 的输入规则。
代码示例:代码语言:javascript复制char str[50];
scanf("%[^\n]", str); // 读取一行(直到换行符)
scanf("%[a-z]", str); // 只读取小写字母常见用法: %[^\n]:读取一行(含空格)。
%[^,]:读取直到逗号。
2. %n用途:记录已输出的字符数(不消耗参数)。
代码示例:代码语言:javascript复制int count;
printf("Hello%nWorld\n", &count); // count = 5("Hello"的长度)3. %*s(抑制赋值)用途:跳过输入的字符串。
代码示例:代码语言:javascript复制char str[10];
scanf("%*s %s", str); // 跳过第一个单词,读取第二个二、C语言字符串的库函数
由于
1、字符串基本操作(1) strlen(长度计算)代码语言:javascript复制size_t len = strlen(str); // 不计算'\0'(2) strcpy(复制)代码语言:javascript复制strcpy(char dest[] , const char arc[]); // 可能溢出功能:将src字符串复制到dest字符串(2.1)strncpy(复制):代码语言:javascript复制strncpy(dest, src, n); // 最多复制n个字符功能:strncpy可以指定最大复制字符数(3) strcat(连接)代码语言:javascript复制strcat(dest, src); // 可能溢出(3.1)strncat(连接)代码语言:javascript复制strncat(dest, src, n); // 最多连接n个字符(4) strcmp(比较)代码语言:javascript复制int strcmp(const char str1[], const char str2[]);功能:比较两个字符串(4.1)strncmp(比较)代码语言:javascript复制int strncmp(const char str1[], const char str2[], size_t n);功能:指定几个字符进行比较 返回值:
0:相等负数:str1小于str2正数:str1大于str2代码示例:
代码语言:javascript复制if(strcmp("apple", "banana") < 0) {
printf("apple在banana前面");
}2、内存操作函数(1)memset(内存设置)代码语言:javascript复制void memset(char arr[], int value, size_t num);功能:将arr数组的前num个字节设置为value,常用于初始化数组代码示例:
代码语言:javascript复制char buffer[50];
memset(buffer, 0, 50); // 将buffer全部初始化为0(2)memcpy(内存复制)代码语言:javascript复制void memcpy(char dest[], const char src[], size_t num);功能:从src数组复制num个字节到dest数组代码示例:
代码语言:javascript复制int src[5] = {1,2,3,4,5};
int dest[5];
memcpy(dest, src, sizeof(src)); // 复制整个数组3、内存查找函数(1) strchr(查找字符位置)代码语言:javascript复制int strchr(const char str[], int c);功能:查找字符c在str中第一次出现的位置,返回字符的索引位置,找不到返回-1代码示例:
代码语言:javascript复制int pos = strchr("Hello", 'l'); // pos现在是2(2) strstr(查找子串位置)代码语言:javascript复制int strstr(const char haystack[], const char needle[]);功能:在haystack中查找needle,返回子串开始的位置索引,找不到返回-1代码示例:
代码语言:javascript复制int pos = strstr("Hello world", "wor"); // pos现在是6 注意事项
使用这些函数时要确保目标数组足够大
字符串必须以’\0’结尾
数组索引从0开始计算
记得包含头文件 #include
三、小编附言 为了方便大家的理解,本期的字符串没有附带指针的内容,后续讲指针的时候,会与字符串联系在一起讲
看到这里麻烦给个三连吧