C语言字符串处理函数详解:存储、拷贝、连接与比较

Mia
Mia
发布时间:2026-10-16| 6人浏览过
原创

C语言通过字符数组和指针管理字符串,标准库提供了一系列高效的处理函数。本文将详细解析字符串的存储结构,并深入讲解如何正确使用strlen获取长度、strncpy实现安全拷贝、strncat进行限定连接,以及strcmp精确比较字符串,结合代码实例揭示各函数的返回值机制与潜在的内存风险。

字符串的存储与表示

在C语言中,字符串本质上是连续存储的字符数组,并以空字符'\0'作为结束标志。了解其底层存储对于理解后续函数的行为至关重要。

字符数组的初始化

可以直接使用双引号包裹的字符串常量来初始化字符数组。系统会自动在末尾添加'\0'。

获取字符串长度:strlen

第1步:调用strlen计算有效长度

目的:获取字符串中实际字符的数量(不包含结尾的'\0')。

入口:strlen(const char *str),需包含头文件<string.h>。

动作与参数:传入字符串指针。strlen返回值为无符号整数size_t,即字节长度。

注意:

  • 长度 vs 尺寸:该函数返回的是内容长度,而非数组分配的内存大小(尺寸)。若需获取数组总字节数,应使用sizeof(str)。
  • 输出格式:由于返回类型为无符号数,建议使用%u或%zu格式输出,避免使用有符号的%d产生混淆。

示例代码:

#include<stdio.h>
#include<string.h>

int main()
{
    char str[] = "i love fishc.com!";
    
    // sizeof 计算包括 '\0' 在内的总字节数
    printf("sizeof(str)= %lu\n", sizeof(str));
    
    // strlen 仅计算非零字符的数量
    printf("strlen(str)= %u\n", strlen(str));
        
    return 0;
}

拷贝字符串:strcpy 与 strncpy

第2步:使用strcpy进行完全拷贝

目的:将源字符串完整复制到目标缓冲区。

入口:strcpy(char *dest, const char *src)。

动作与参数:指定目标数组dest和源字符串src。

风险提示:

  • 无法防止溢出:C语言不检查数组边界。如果src长于dest,将导致内存溢出且不会报错,这是常见的安全漏洞。
  • 不可直接复制常量到变量:不能用char str[10] = "original";赋值后,再调用strcpy(str, "new"),因为str此时是只读标识符(除非明确定义为可修改数组),且需注意目标空间是否足够。

示例代码:

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "original string"; // 自动分配足够空间
    char str2[] = "new string";       // 自动分配足够空间
    char str3[100];                  // 手动分配大空间

    strcpy(str1, str2);              // 将 str2 的内容拷贝给 str1
    strcpy(str3, "copy successful"); // 将字面量拷贝给 str3
    
    printf("str1:%s\n", str1);       
    printf("str2:%s\n", str2);       
    printf("str3:%s\n", str3);           
        
    return 0;
}

第3步:使用strncpy进行限制拷贝

目的:控制拷贝的字符数量,提高安全性。

入口:strncpy(char *dest, const char *src, size_t n)。

动作与参数:第三个参数n指定最大拷贝字符数。

关键行为:

  • 源短于n:如果在拷贝完src后仍未达到n个字符,剩余空间会用'\0'填充。
  • 源长于等于n:只会拷贝前n个字符,且不会自动追加结束符'\0'。
  • 必须手动补零:当使用strncpy且可能遇到截断时,务必手动为结果字符串的最后一位设置'\0',否则后续打印会出现乱码。

示例代码:

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "to be or not to be";
    char str2[40];
    
    strncpy(str2, str1, 5); // 仅拷贝前5个字符 't', 'o', ' ', 'b', 'e'
    str2[5] = '\0';        // 关键:手动添加结束符
    
    printf("str2:%s\n", str2);         
        
    return 0;
}

连接字符串:strcat 与 strncat

第4步:使用strcat追加字符串

目的:将一个字符串附加到另一个字符串的末尾。

入口:strcat(char *dest, const char *src)。

动作:找到dest的'\0'位置,开始覆盖写入src的内容,并在最后重新写入新的'\0'。

注意:strncat类似于strncpy,第三个参数限制要追加的字符数。不同之处在于,strncat在追加完成后会自动追加结束符'\0',不需要像strncpy那样手动处理。

示例一:基本拼接

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "to be or not to be";
    char str2[] = "fishc.com!";
    
    strcat(str1, " ");      // 先加一个空格,仅为美观
    strcat(str1, str2);     // 将 str2 拼接到 str1 后
    
    printf("str1:%s\n", str1);
    
    return 0;
}

示例二:限定拼接

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "to be or not to be";
    char str2[] = "fishc.com!";
    
    // 第二个参数是待追加的字符串,第三个参数限制追加个数
    strncat(str1, " ", 2);  // 尝试追加空格,但长度受限
    strncat(str1, str2, 5);  // 仅截取 str2 的前5个字符 'f', 'i', 's', 'h', 'c'
    // strncat 会自动补 '\0',无需额外操作
                             
    printf("str1:%s\n", str1); 
    
    return 0;
}

比较字符串:strcmp 与 strncmp

第5步:使用strcmp比较字符串

目的:按字典序比较两个字符串的大小。

入口:strcmp(const char *s1, const char *s2)。

返回值解析:

  • 返回值 < 0:s1 小于 s2。
  • 返回值 > 0:s1 大于 s2。
  • 返回值 == 0:两字符串相等。

判断技巧:若要判断两个字符串是否相等,通常写成 if (strcmp(s1, s2) == 0) 或使用逻辑非运算符 if (!strcmp(s1, s2)),因为相等时返回值为0(假)。

示例代码:

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "fishc.com!";
    char str2[] = "fishc.com!";
    
    if (!strcmp(str1, str2)) // strcmp 返回 0,取反后为真
    {
        printf("两个字符串完全一致!\n");
    }
    else
    {
        printf("两个字符串存在差异!\n");
    }
    
    return 0;
}

第6步:使用strncmp限制比较范围

目的:仅比较字符串的前N个字符,常用于匹配特定协议头或固定前缀。

区别:strncmp(s1, s2, n) 在第三个参数n指定的范围内进行比较。逻辑与strcmp相同。

示例代码:

#include<stdio.h>
#include<string.h>

int main()
{
    char str1[] = "fishc.cfm!";
    char str2[] = "fishc.com!";
    
    // 仅比较前5个字符 "fishc"
    if (!strncmp(str1, str2, 5)) 
    {
        printf("前5个字符完全一致!\n");                                          
    }                
    else                                        
    {                  
        printf("前5个字符存在差异!\n");
    }                                     
    
    return 0;
}

以上就是C语言字符串处理函数的详细内容,更多关于C语言基础知识、内存管理与常用库函数应用的文章请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。