C 语言 字符串
在 C 语言中,字符串 是由一系列字符组成的数组。C 语言没有内建的字符串类型,而是通过字符数组来实现字符串。因此,理解 C 中的字符串包括字符数组的操作、常见函数以及相关的内存管理非常重要。
1. C 字符串的基本定义
在 C 中,字符串是由字符数组表示的,并且以 空字符 \0 结束。'\0' 是一个标志,用来标识字符串的结束。
1.1 字符串声明与初始化
char str1[] = "Hello, World!"; // 自动分配大小并包含 '\0'
char str2[20] = "Hello"; // 手动分配大小
char str3[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 手动定义字符串
str1:这个字符串会隐式包含一个\0字符,因此其大小为14字节(13 个字符 + 1 个\0)。str2:这里我们指定了20字节,但只初始化了前 6 个字符,其余字符会被自动填充为\0。str3:这是一个手动创建字符串的方式,显式指定了结尾的\0。
2. C 字符串的操作
C 语言没有像其他高级语言那样的字符串类或对象。所有的字符串操作都基于字符数组及相关函数。下面是一些常见的字符串操作函数和技巧。
2.1 字符串输入与输出
#include <stdio.h>
int main() {
char str[50];
// 输入字符串
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); // 安全的字符串输入方式
// 输出字符串
printf("You entered: %s", str);
return 0;
}
fgets:比scanf更安全,能够防止缓冲区溢出。printf:使用%s来打印字符串。
2.2 字符串长度
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
int length = strlen(str); // 计算字符串长度(不包括 '\0')
printf("Length of string: %d\n", length);
return 0;
}
strlen:返回字符串的长度,不包括空字符\0。
2.3 字符串连接
#include <stdio.h>
#include <string.h>
int main() {
char str1[50] = "Hello, ";
char str2[] = "World!";
strcat(str1, str2); // 连接 str2 到 str1
printf("Concatenated string: %s\n", str1);
return 0;
}
strcat:将一个字符串连接到另一个字符串的末尾。
2.4 字符串复制
#include <stdio.h>
#include <string.h>
int main() {
char str1[50];
char str2[] = "Hello, World!";
strcpy(str1, str2); // 将 str2 复制到 str1
printf("Copied string: %s\n", str1);
return 0;
}
strcpy:将一个字符串复制到另一个字符串。
2.5 字符串比较
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello";
char str2[] = "World";
int result = strcmp(str1, str2); // 比较两个字符串
if (result == 0) {
printf("Strings are equal.\n");
} else if (result < 0) {
printf("str1 is less than str2.\n");
} else {
printf("str1 is greater than str2.\n");
}
return 0;
}
strcmp:比较两个字符串,返回值:- 0 表示相等
- 小于 0 表示第一个字符串小于第二个
- 大于 0 表示第一个字符串大于第二个
2.6 字符串查找
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *ptr = strchr(str, 'o'); // 查找字符 'o' 第一次出现的位置
if (ptr != NULL) {
printf("Found 'o' at: %s\n", ptr);
} else {
printf("'o' not found.\n");
}
return 0;
}
strchr:返回指向字符串中第一次出现指定字符的指针。
3. C 字符串的内存管理
由于 C 字符串是基于字符数组实现的,涉及到内存管理时需要小心避免越界和内存泄漏。
3.1 字符数组与指针
字符串可以存储在字符数组或字符指针中:
char str1[] = "Hello, World!"; // 字符数组
char *str2 = "Hello, World!"; // 字符指针
str1是一个字符数组,包含字符和结尾的\0。str2是一个指向字符串常量的指针。
3.2 动态内存分配
通过 malloc 或 calloc 动态分配字符串的内存:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *str = (char *)malloc(50 * sizeof(char)); // 动态分配内存
if (str != NULL) {
strcpy(str, "Dynamic String");
printf("Allocated String: %s\n", str);
free(str); // 释放内存
}
return 0;
}
malloc:动态分配内存,但不会初始化。calloc:动态分配内存,并初始化为 0。free:释放动态分配的内存。
4. 字符串与其他类型的转换
4.1 字符串转整数
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "12345";
int num = atoi(str); // 将字符串转换为整数
printf("Converted number: %d\n", num);
return 0;
}
atoi:将字符串转换为整数(如果字符串无法转换为数字,返回 0)。
4.2 整数转字符串
#include <stdio.h>
#include <stdlib.h>
int main() {
int num = 12345;
char str[50];
sprintf(str, "%d", num); // 将整数转换为字符串
printf("Converted string: %s\n", str);
return 0;
}
sprintf:将数字或其他数据格式化为字符串。
5. 常见问题和注意事项
5.1 字符串溢出
C 字符串不自动检查数组越界,因此需要特别小心,确保字符串长度不超过数组的大小。例如:
char str[5];
strcpy(str, "Hello"); // 错误,字符串长度超过数组大小
5.2 字符串比较时的大小写
C 中的字符串比较是区分大小写的,如果要忽略大小写,可以使用 strcasecmp(在某些平台上)或者通过手动转换字符串为小写或大写进行比较。
6. 总结
| 操作 | 函数名称 | 描述 |
|---|---|---|
| 获取字符串长度 | strlen | 获取字符串的长度 |
| 字符串连接 | strcat | 连接两个字符串 |
| 字符串复制 | strcpy | 复制一个字符串 |
| 字符串比较 | strcmp | 比较两个字符串 |
| 字符串查找 | strchr | 查找指定字符 |
| 字符串转整数 | atoi | 将字符串转为整数 |
| 整数转字符串 | sprintf | 将整数转为字符串 |