C语言字符串核心函数解析:strlen、strcpy与排序实战
深入理解C语言字符串的底层存储机制,掌握 strlen、strcpy、strncpy、strcat、strncat 及 strcmp、strncmp 等核心函数的正确用法与安全边界控制,并通过实际编程案例实现字符串数据的排序处理。
C语言中的字符串表示
在C语言中,字符串常量是用双引号括起来的一系列字符。编译器会自动在末尾添加一个空字符 '\0' 作为字符串结束的标志。这些字符连同结束的 '\0' 都会存储在静态存储区中。当在函数内使用字符串常量时,它本质上是指向该存储位置的一个指针。
可以通过以下代码验证字符串常量的指针特性及格式化输出的行为:
/* strptr.c -- 把字符串看做指针 */
#include
int main(void) {
printf("%s, %p, %c\n", "Who", "you", *"are");
return 0;
}
上述程序的输出结果为:Who, 0x400668, a。这里展示了如何访问字符串首字符(*"are" 为 'a'),以及字符串常量在内存中的地址表现形式。
字符串长度获取:strlen
第1步:引入头文件与函数声明
在使用 strlen 函数前,必须包含标准库头文件 #include <string.h>。
函数原型如下:
size_t strlen(const char *s);
第2步:计算长度与应用场景
功能说明:返回指定字符串 s 的实际字符长度,不包含结尾的 '\0' 字符。空格也被计入长度。
返回值:类型为 size_t,即无符号整数。
实例代码:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello world";
int len = strlen(str);
printf("%d\n", len); // 输出 11
return 0;
}
字符串拷贝:strcpy 与 strncpy
第3步:基础拷贝 strcpy
函数声明:char *strcpy(char *dest, const char *src);
功能说明:将 src 指向的整个字符串(包括 '\0')复制到 dest 指向的内存地址中。
风险提示:此函数不检查目标缓冲区的容量。若 dest 空间不足以容纳 src,将导致缓冲区溢出和内存污染。
返回值:返回 dest 的地址。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char str[14] = "hello world";
char s[] = "hello earth";
strcpy(str, s);
printf("%s\n", str); // 打印 hello earth
return 0;
}
第4步:受限拷贝 strncpy
函数声明:char *strncpy(char *dest, const char *src, size_t n);
功能说明:仅拷贝 src 的前 n 个字节。需要注意两个关键细节:
strncpy不会自动追加'\0',除非原始字符串长度小于n。- 如果
n大于src的长度,剩余部分将在dest后面填充'\0'。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char str[20] = "hello world";
char s[] = "hello earth";
// 拷贝前8个字节
strncpy(str, s, 8);
printf("%s\n", str);
return 0;
}
字符串连接:strcat 与 strncat
第5步:追加连接 strcat
函数声明:char *strcat(char *dest, const char *src);
功能说明:将 src 连接到 dest 的末尾,覆盖 dest 原有的 '\0',并在新字符串末尾追加新的 '\0'。
注意:务必保证 dest 有足够空间存放原内容加上 src 的内容。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char str[100] = "hello world";
char s[] = " my friend";
strcat(str, s);
printf("%s\n", str); // 连接后字符串
return 0;
}
第6步:受限连接 strncat
函数声明:char *strncat(char *dest, const char *src, size_t n);
功能说明:将 src 的前 n 个字符追加到 dest 之后。函数会自动在拼接后的新字符串末尾添加 '\0'。
注意:如果 n 超过了 src 的有效长度,则只追加 src 的全部字符并补全结束符。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char str[100] = "hello world";
char s[] = "hello";
// 只追加前4个字符
strncat(str, s, 4);
printf("%s\n", str);
return 0;
}
字符串比较:strcmp 与 strncmp
第7步:完全比较 strcmp
函数声明:int strcmp(const char *s1, const char *s2);
功能说明:逐个字符比较 s1 和 s2 的 ASCII 码值,直到遇到 '\0' 或字符不相等为止。
返回值规则:
- 若
s1大于s2,返回正值; - 若
s1等于s2,返回0; - 若
s1小于s2,返回负值。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "abc";
char str2[] = "xyz";
int ret = strcmp(str1, str2);
// ret 将为负数,因为 'a' < 'x'
printf("%d\n", ret);
return 0;
}
第8步:部分比较 strncmp
函数声明:int strncmp(const char *s1, const char *s2, size_t n);
功能说明:仅比较两个字符串的前 n 个字符。其返回值规则同 strcmp。
实例:
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "hello world";
char s2[] = "hello earth";
int ret;
// 比较前5个字符
ret = strncmp(s1, s2, 5);
if (ret > 0)
printf("s1的前五个字符大于s2的前五个字符\n");
else if (ret < 0)
printf("s1的前五个字符小于s2的前五个字符\n");
else
printf("s1的前五个字符等于s2的前五个字符\n");
return 0;
}
综合实战:基于字符串的操作排序
在实际应用中,常常需要将字符串数据进行逻辑处理。下面展示一个常见的场景:读取多行身份证号(假设身份证号前部分是日期),提取出生日期部分并按年龄降序排列(即出生日期从小到大/年份数字大的排前,具体逻辑依题目要求而定,此处演示按整体字符串字典序或特定字段排序的逻辑框架)。
由于身份证号码是定长且格式固定的字符串,我们可以利用子串截取和比较来实现排序。以下代码演示了使用 strncpy 提取关键字段并进行冒泡排序的基本思路:
#include <stdio.h>
#include <string.h>
int main() {
// 假设有 n 条数据
int n, i, j;
scanf("%d", &n);
char data[100][100];
char temp[100];
// 读取 n 行数据,忽略缓冲区遗留换行
char buffer[10];
gets(buffer);
for(i = 0; i < n; i++) {
gets(data[i]);
}
// 简单的冒泡排序,根据需求调整比较逻辑
// 此处为了演示字符串处理,暂时按整行字典序交换进行示意
for(i = 0; i < n - 1; i++) {
for(j = 0; j < n - 1 - i; j++) {
// 示例:如果需要按年龄排序,通常需要像下面这样截取特定位置的年份字符串进行比较
// 这里简化为通用的字符串移动逻辑
if (strcmp(data[j], data[j+1]) > 0) { // 改为 < 0 可实现倒序
strcpy(temp, data[j]);
strcpy(data[j], data[j+1]);
strcpy(data[j+1], temp);
}
}
}
// 输出结果
for(i = 0; i < n; i++) {
printf("%s\n", data[i]);
}
return 0;
}
以上便是关于 C 语言字符串基础表示、核心处理函数及其进阶应用的详细内容,更多关于 C 语言字符串操作的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









