使用标准库函数 strlen() (最常用、最推荐)
这是最标准、最安全、最常用的方法。strlen() 函数定义在 <string.h> 头文件中。
函数原型
size_t strlen(const char *str);
- 参数:
str是一个指向以空字符'\0'结尾的字符串的指针。 - 返回值:返回字符串的长度,不包括结尾的空字符
'\0'。 - 返回类型:
size_t,这是一个无符号整型类型(通常是unsigned int或unsigned long)。
特点
- 高效:
strlen()通常通过遍历字符串直到遇到'\0'来实现,时间复杂度为 O(n)。 - 安全:它明确要求字符串必须以
'\0'如果传入的不是合法的C字符串(一个字符数组没有'\0'),会导致缓冲区溢出,程序可能崩溃或产生不可预测的结果。
代码示例
#include <stdio.h>
#include <string.h> // 必须包含此头文件
int main() {
char str1[] = "Hello, World!";
char str2[] = "C Programming";
char str3[] = ""; // 空字符串
// 使用 strlen() 计算字符串长度
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
size_t len3 = strlen(str3);
printf("The length of \"%s\" is %zu\n", str1, len1); // 输出: The length of "Hello, World!" is 13
printf("The length of \"%s\" is %zu\n", str2, len2); // 输出: The length of "C Programming" is 14
printf("The length of \"%s\" is %zu\n", str3, len3); // 输出: The length of "" is 0
return 0;
}
注意:使用
%zu来打印size_t类型的变量,这是正确的格式说明符。
手动实现 strlen() 函数
为了更好地理解 strlen() 的工作原理,或者在没有标准库的环境下,你可以自己编写一个类似的函数。
实现思路
- 创建一个指针,指向字符串的开头。
- 使用一个循环,逐个移动指针,直到遇到空字符
'\0'。 - 计算移动过的字符数量,这个数量就是字符串的长度。
代码示例
#include <stdio.h>
// 自定义的字符串长度计算函数
size_t my_strlen(const char *str) {
size_t length = 0;
// 当指针指向的字符不是 '\0' 时,循环继续
while (*str != '\0') {
length++;
str++; // 指针移动到下一个字符
}
return length;
}
int main() {
char str[] = "Manual Implementation";
size_t len = my_strlen(str);
printf("The length of \"%s\" is %zu\n", str, len); // 输出: The length of "Manual Implementation" is 21
return 0;
}
这个 my_strlen() 函数的行为与标准库的 strlen() 完全一致。
使用 sizeof 运算符 (非常特殊,容易误用)
sizeof 是一个编译时运算符,用于返回变量或类型的大小(以字节为单位)。只有在特定情况下,它才能用来“计算”字符串长度。
适用场景
仅适用于在定义时初始化的字符数组,并且你想要获取整个数组的大小时。
特点
sizeof返回的是整个数组所占的总字节数,而不是字符串的长度。- 如果字符数组中包含空字符
'\0',sizeof的结果会大于strlen的结果。 - 如果数组的大小大于字符串的实际长度(
char str[100] = "hi";),sizeof返回的是100,而不是2。 - 绝对不能将
sizeof用于一个指向字符串的指针,因为它只会返回指针本身的大小(通常是4或8字节),而不是指向的字符串的长度。
代码示例
#include <stdio.h>
int main() {
// 场景1:字符数组在定义时初始化
char str1[] = "Hello"; // 编译器会自动在末尾添加 '\0',str1 实际上是 ['H','e','l','l','o','\0']
// sizeof(str1) 计算的是整个数组的大小,包括 '\0'
// strlen(str1) 计算的是字符的个数,不包括 '\0'
printf("sizeof(str1) = %zu\n", sizeof(str1)); // 输出: sizeof(str1) = 6
printf("strlen(str1) = %zu\n", strlen(str1)); // 输出: strlen(str1) = 5
// 场景2:定义了一个足够大的数组,但只初始化了一部分
char str2[100] = "Hi";
printf("sizeof(str2) = %zu\n", sizeof(str2)); // 输出: sizeof(str2) = 100
printf("strlen(str2) = %zu\n", strlen(str2)); // 输出: strlen(str2) = 2
// 场景3:使用指针(错误示范)
char str3[] = "Test";
char *ptr = str3;
printf("sizeof(ptr) = %zu\n", sizeof(ptr)); // 输出: sizeof(ptr) = 8 (在64位系统上) 或 4 (在32位系统上)
// printf("strlen(ptr) = %zu\n", strlen(ptr)); // 这个是正确的,但 sizeof(ptr) 是错误的
return 0;
}
除非你明确地想知道整个字符数组的总大小,否则永远不要用 sizeof 来计算字符串的长度,99% 的情况下,你应该使用 strlen()。
总结与对比
| 方法 | 函数/运算符 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
strlen() |
标准库函数 | 标准、安全、可读性高 | 需要包含 <string.h> |
计算以 '\0' 结尾的字符串长度的首选方法。 |
| 手动实现 | 自定义函数 | 理解原理、无依赖 | 需要自己编写代码 | 学习目的,或在没有标准库的受限环境中。 |
sizeof |
运算符 | 编译时计算,无运行时开销 | 极易误用,结果含义不同 | 仅用于获取字符数组的总大小,绝不能用于计算字符串长度。 |
最佳实践
在C语言编程中,当你需要获取一个字符串的长度时,请遵循以下黄金法则:
- 始终使用
strlen(),这是最正确、最安全、最符合C语言习惯的做法。 - 确保你的字符串是以
'\0'结尾的,这是strlen()正确工作的前提,当你使用字符字面量(如"text")或strcpy等函数时,这一点通常能得到保证。 - 避免使用
sizeof来计算字符串长度,除非你100%确定你想要的是整个数组的大小,而不是字符串本身的长度。
