C语言常见字符函数和字符串函数精讲

发布于:2025-05-12 ⋅ 阅读:(22) ⋅ 点赞:(0)

字符/字符串函数

01.求字符串长度

1.1strlen()函数原型

size_t strlen(const char *str);

参数: str:要计算长度的字符串的首地址

功能: 从给定内存地址开始扫描,直到遇到第一个'\0'结束符为止,统计这之间的字符数量。

返回值: 返回一个 size_t 类型的值,表示字符串中的字符数。(不包括空字符’\0’)

1.2模拟实现my_strlen()

//非递归求字符串长度
int My_Strlen(char* str){
    int count = 0;//临时变量
    while (*str!='\0'){//传递的是字符串首地址,,解引用即可
        count++;
        str++;//找下一个字符
    }return count;
}
//递归
int My_Strlen(char* str){
    if (*str!='\0'){
        return 1 + My_Strlen(str + 1);//加一个字符串的长度
    }return 0;
}
int main(){
    char arr[] = "zbc";//['z','b','c','\0']包括'\0'
    int len = My_Strlen(arr);//传递的是数组的首地址过去
    return 0;
}

1.3 sizeof()简述

  1. sizeof 操作符在编译时求值,不会引起运行时开销
  2. sizeof 可以用于任何数据类型,包括用户自定义类型
  3. sizeof 的返回值类型是 size_t(无符号整数类型)
  4. sizeof 可以使用两种语法形式: sizeof(类型名)sizeof 表达式

1.4 深入解析 strlen()sizeof ()的区别

一般情况下数组名表示首地址的地址,但是有特殊情况sizeof(数组名)&数组名(取出整个数组的地址,是一个随机值)表示的是整个数组的大小。strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为’\0’的数组元素。 而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。

示例代码:

char text[100] = "Programming";
printf("strlen: %zu\n", strlen(text));  // 11
printf("sizeof: %zu\n", sizeof(text));  // 100
-----
char *ptr = "Hello World";
printf("strlen: %zu\n", strlen(ptr));  // 11
printf("sizeof: %zu\n", sizeof(ptr));  // 4或8(指针大小)

内存布局:

示例字符串"Hello"的内存表示:
+-----+-----+-----+-----+-----+-----+
| 'H' | 'e' | 'l' | 'l' | 'o' | '\0'|
+-----+-----+-----+-----+-----+-----+
 0x00  0x01  0x02  0x03  0x04  0x05
 
strlen结果:5(0x00-0x04)
sizeof结果:6(整个数组大小)

02.长度不受限制的字符串函数

char *strcpy(char *dest, const char *src);//将源字符串复制到目标串中,并在目标串末尾添加空字符'\0'。

2.1 strcpy()

参数: dest: 目标字符串地址 src: 源字符串地址

功能:src 指向的字符串(包括空字符 \0复制dest 指向的内存中。

返回值: 返回 dest 的地址

2.1.1 模拟实现my_strcpy()
char* My_Srecpy(char* dest, const char* src){
    char *ret = dest;
    assert(dest != NULL);
    assert(src != NULL);
    while(*dest != *src){
        dest++;
        src++;
    }
    return ret;
}

char* strcat(char* dest, const char* src);

2.2 strcat ()

参数: dest: 目标字符串地址src: 源字符串地址

功能:src 指向的字符串追加到 dest 的末尾(覆盖 dest 的 \0)。

返回值: 返回 dest的地址

注意: 两常量字符串能拼接说明:srcdest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。在str为NULL的情况下调用strcpystrcat,试图往空指针指向的内存空间写入数据,这会导致程序崩溃。

2.2.1 模拟实现My_Strcat()
char* My_Strcat(char* dest, const char* src){
    char *ret = dest;
    assert(dest != NULL);
    assert(src != NULL);
    while(*dest !=NULL){
        dest++;
    }
    while((*dest++ = *src++)){
      ;
    }
    return ret;
}

int strcmp(const char* str1, const char* str2);

2.3 strcmp()

参数: str1: 字符串1地址;str2: 字符串2地址

功能: 比较 str1str2 的字典顺序(按ASCII值逐字符比较)。

返回值: 返回整数:(str1 < str2),返回负值,(str1 == str2),返回0,若 (str1 > str2),返回正值

2.3.1 模拟实现My_Strcmp()
int strcmp(const char* str1, const char* str2){//比较的是ascii码值,需要转换,逐字符比较
    int ret = 0;
    assert(dest != NULL);
    assert(src != NULL);
    while(*str1 != '\0' && *str2 != '\0' && *str1 == *str2){
        srt1++;
        str2++;
	}
    return (*str1 - *str2)
}

03.长度受限制的字符串介绍

char *strncpy(char *dest, const char *src, size_t n);

3.1 strncpy ()

参数:

dest:目标字符串的地址,它需要有足够空间容纳源字符串n字符和空字符’\0’

src: 源字符串的地址,以’\0’结束。

n: 需要复制的字节数

功能: strncpysrc 的前 n 个字符复制到 dest:若 src 长度不足 n,剩余部分用 \0 填充;若 src 长度 ≥ n,则只复制前 n 个字符且不自动补 \0,需手动添加以确保字符串合法。

返回值: 返回指向目标字符串的dest 指针。

注意:

  • dest 必须足够大(至少 n 字节),否则可能溢出。
  • 不会自动补 \0(当 n ≤ strlen(src) 时),需手动处理:
  • 性能较低(如果 n 远大于 strlen(src),会填充大量 \0)。
  • 不适合直接用于字符串操作(除非手动处理 \0)。

代码示例:

int main() {
    char dest[10];
    const char *src1 = "Hello";
    const char *src2 = "World12345";
    // 当 src < n(自动补 \0)
    strncpy(dest, src1, 10);
    printf("Case 1: %s\n", dest);  // 输出 "Hello"(后面填充 \0)
    // 当 src ≥ n(不补 \0)
    strncpy(dest, src2, 5);
    dest[5] = '\0';  // 手动补余 \0
    printf("Case 2: %s\n", dest);  // 输出 "World"
    return 0;
}

char *strncat(char *dest, const char *src, size_t n);

3.2 strncat ()

参数:

dest:目标字符串的地址,它需要有足够空间容纳拼接后的字符串和空字符’\0’

src:源字符串的指针的首地址

n:最多追加的字符数(不包括自动添加的 \0

功能:src 的前 n 个字符(或遇到 \0 时停止)追加到 dest 的末尾,并自动在最终结果后补 \0。能够防止dest溢出,安全拼接字符串(比 strcat 更安全)。

**返回值:**返回指向目标字符串的dest 指针。

注意:

  • dest 必须有足够的剩余空间(至少 strlen(dest) + n + 1)。
  • dest 必须以\0开头(否则行为未定义)。
  • n 仅限制 src 的字符数,strncat 始终会补 \0(即使 n 个字符后没有 \0)。
  • 不会检查 dest 缓冲区是否足够大,需程序员自行确保。

代码示例:

int main(){
	char dest[20] = "Hello";
    const char *src = ", World!";
    strncat(dest, src, 5);  // 只追加 ", Wor"(5 个字符)
    printf("%s\n", dest);   // 输出 "Hello, Wor"(自动补 \0)
    return 0;
}

int strncmp(const char *s1, const char *s2, size_t n);

3.3 strncmp ()

参数:

s1:要比较的第一个字符串

s2:要比较的第二个字符串

n:最多比较的字符数(比较前 n 个字符)

功能: 逐字符比较 str1str2 的前 n 个字符(或直到遇到 \0)。

返回值:

  1. n个字符相同 → 返回0
  2. 比较中s1字符 < s2字符 → 返回负值
  3. 比较中s1字符 > s2字符 → 返回正值

注意:

  • 不会自动检查字符串长度,n 不可超过缓冲区大小。
  • 遇到 \0 会提前终止比较(即使 n 未用完)。
  • 不适用于非字符串数据(如二进制数据,应使用 memcmp)。

代码示例:

int main() {
    const char *s1 = "Hello";
    const char *s2 = "Hellx";
    const char *s3 = "Ha";
    printf("strncmp(s1, s2, 4): %d\n", strncmp(s1, s2, 4));  // 0  
    printf("strncmp(s1, s2, 5): %d\n", strncmp(s1, s2, 5));  //-11 <0('o' < 'x')
    printf("strncmp(s1, s3, 2): %d\n", strncmp(s1, s3, 2));  // 4 >0('e' > 'a')
    return 0;
}

更新中…

04.字符串查找

strstr

参数:

功能:

**返回值: **

strtok

参数:

功能:

**返回值: **

05.错误信息报告

strerror

参数:

功能:

**返回值: **

06.字符操作

07.内存操作函数

memcpy

参数:

功能:

**返回值: **

memmove

参数:

功能:

**返回值: **

memset

参数:

功能:

**返回值: **

memcmp

参数:

功能:

**返回值: **


网站公告

今日签到

点亮在社区的每一天
去签到