目录

一、字符分类函数

二、字符转换函数

三、字符串长度函数strlen

1. 函数功能与特性

2. 模拟实现

四、字符串复制函数strcpy与strncpy

1. strcpy

2. strncpy

五、字符串追加函数strcat与strncat

1. strcat

2. strncat

六、字符串比较函数strcmp与strncmp

1. strcmp

2. strncmp

七、字符串查找函数strstr

八、字符串分割函数strtok

九、错误信息函数strerror

十、面试考察要点


一、字符分类函数

C 语言提供了一系列字符分类函数,用于判断字符的类型,这些函数均需包含头文件<ctype.h>。它们的返回值规则统一:符合条件返回非 0 整数,不符合返回 0。

常见函数及判断条件:

  • iscntrl:判断是否为控制字符
  • isspace:判断是否为空白字符(空格、换页、换行、回车、制表符等)
  • isdigit:判断是否为十进制数字(0~9)
  • isxdigit:判断是否为十六进制数字(0~9、a~f、A~F)
  • islower:判断是否为小写字母(a~z)
  • isupper:判断是否为大写字母(A~Z)
  • isalpha:判断是否为字母(a~z 或 A~Z)
  • isalnum:判断是否为字母或数字
  • ispunct:判断是否为标点符号(非数字、字母的图形字符)
  • isgraph:判断是否为图形字符
  • isprint:判断是否为可打印字符(含图形字符和空白字符)

示例:将字符串中的小写字母转为大写,其他字符不变

#include <stdio.h>
#include <ctype.h>
int main() {
    int i = 0;
    char str[] = "Test String.\n";
    char c;
    while (str[i]) {
        c = str[i];
        if (islower(c)) // 判断是否为小写字母
            c -= 32; // 转为大写(ASCII码差值)
        putchar(c);
        i++;
    }
    return 0;
}

二、字符转换函数

C 语言提供两个字符转换函数:

  • int tolower(int c):将大写字母转为小写
  • int toupper(int c):将小写字母转为大写

示例:使用toupper优化上述小写转大写代码

#include <stdio.h>
#include <ctype.h>
int main() {
    int i = 0;
    char str[] = "Test String.\n";
    char c;
    while (str[i]) {
        c = str[i];
        if (islower(c))
            c = toupper(c); // 直接调用转换函数
        putchar(c);
        i++;
    }
    return 0;
}

三、字符串长度函数strlen

1. 函数功能与特性

size_t strlen(const char *str)用于计算字符串长度,返回\0之前的字符个数(不含\0)。

使用注意:

  • 字符串必须以\0结束。
  • 返回值为size_t(无符号整数),可能导致运算逻辑错误。

示例

#include <stdio.h>
#include <string.h>
int main() {
    const char* str1 = "abcdef";
    const char* str2 = "bbb";
    // 因返回值为无符号数,3-6的结果为正数,会打印"str2>str1"
    if (strlen(str2) - strlen(str1) > 0)
        printf("str2>str1\n");
    else
        printf("str1>str2\n");
    return 0;
}

2. 模拟实现

  • 方式 1:计数器法

    #include <assert.h>
    int my_strlen(const char *str) {
        assert(str); // 确保指针非空
        int count = 0;
        while (*str) { // 遍历至\0结束
            count++;
            str++;
        }
        return count;
    }
    
  • 方式 2:递归法(无临时变量)

    #include <assert.h>
    int my_strlen(const char *str) {
        assert(str);
        if (*str == '\0')
            return 0;
        else
            return 1 + my_strlen(str + 1);
    }
    
  • 方式 3:指针 - 指针法

    #include <assert.h>
    int my_strlen(char *s) {
        assert(s);
        char *p = s;
        while (*p != '\0')
            p++;
        return p - s; // 指针差值即为长度
    }
    

四、字符串复制函数strcpystrncpy

1. strcpy

char *strcpy(char *destination, const char *source)将源字符串复制到目标空间,包括\0

使用规则:

  • 源字符串必须以\0结束。
  • 目标空间需足够大且可修改🔶16-59🔶。

模拟实现

#include <assert.h>
char *my_strcpy(char *dest, const char *src) {
    char *ret = dest; // 保存目标起始地址
    assert(dest && src); // 断言非空指针
    while ((*dest++ = *src++)) { // 复制至\0结束
        ;
    }
    return ret; // 返回目标地址
}

2. strncpy

char *strncpy(char *destination, const char *source, size_t num)复制源字符串的前num个字符到目标空间。

特性:

  • 若源字符串长度小于num,剩余部分用0填充。

五、字符串追加函数strcatstrncat

1. strcat

char *strcat(char *destination, const char *source)将源字符串追加到目标字符串末尾,覆盖目标字符串的\0,并在结果后添加\0

使用规则:

  • 源字符串以\0结束,目标字符串需包含\0(确定追加起始位置)。
  • 目标空间需足够大且可修改。

模拟实现

#include <assert.h>
char *my_strcat(char *dest, const char *src) {
    char *ret = dest;
    assert(dest && src);
    // 找到目标字符串的\0位置
    while (*dest) {
        dest++;
    }
    // 追加源字符串(含\0)
    while ((*dest++ = *src++)) {
        ;
    }
    return ret;
}

2. strncat

char *strncat(char *destination, const char *source, size_t num)追加源字符串的前num个字符到目标字符串,自动添加\0

六、字符串比较函数strcmpstrncmp

1. strcmp

int strcmp(const char *str1, const char *str2)比较两个字符串对应位置字符的 ASCII 码值。

返回值规则:

  • 大于 0:第一个字符串大
  • 等于 0:两字符串相等
  • 小于 0:第一个字符串小

模拟实现

#include <assert.h>
int my_strcmp(const char *str1, const char *str2) {
    assert(str1 && str2);
    while (*str1 == *str2) {
        if (*str1 == '\0')
            return 0; // 相等且到\0
        str1++;
        str2++;
    }
    return *str1 - *str2; // 返回差值
}

2. strncmp

int strncmp(const char *str1, const char *str2, size_t num)比较前num个字符,规则同strcmp

七、字符串查找函数strstr

char *strstr(const char *str1, const char *str2)返回str2str1中第一次出现的位置,若未找到返回NULL

模拟实现

#include <assert.h>
char *my_strstr(const char *str1, const char *str2) {
    assert(str1 && str2);
    if (!*str2) // 若str2为空,返回str1
        return (char *)str1;
    char *cp = (char *)str1;
    while (*cp) {
        char *s1 = cp;
        char *s2 = (char *)str2;
        // 匹配子串
        while (*s1 && *s2 && (*s1 == *s2)) {
            s1++;
            s2++;
        }
        if (!*s2) // 找到匹配
            return cp;
        cp++;
    }
    return NULL; // 未找到
}

八、字符串分割函数strtok

char *strtok(char *str, const char *sep)sep中的字符分割字符串。

使用规则:

  • 第一个参数非NULL时,查找第一个标记,保存位置。
  • 第一个参数为NULL时,从保存位置继续查找下一个标记。
  • 无更多标记时返回NULL

示例

#include <stdio.h>
#include <string.h>
int main() {
    char arr[] = "192.168.6.111";
    char *sep = ".";
    char *str = NULL;
    // 循环分割字符串
    for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)) {
        printf("%s\n", str);
    }
    return 0;
}

九、错误信息函数strerror

char *strerror(int errnum)返回错误码对应的错误信息字符串地址。

使用场景:结合全局变量errno(定义于<errno.h>)获取函数调用错误信息。

示例

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
    FILE *pFile = fopen("unexist.ent", "r");
    if (pFile == NULL) {
        // 打印错误信息
        printf("Error: %s\n", strerror(errno));
    }
    return 0;
}

十、面试考察要点

  1. 字符函数:字符分类函数的返回值特性,touppertolower的转换逻辑。
  2. strlen细节:返回值为size_t的陷阱,三种模拟实现方法的差异。
  3. 字符串操作函数strcpystrcat的安全问题(需确保目标空间足够),strncpystrncat的长度控制优势。
  4. 比较函数strcmp的返回值规则,strncmpstrcmp的适用场景。
  5. 综合应用strstr的查找逻辑,strtok的分割机制(状态保存特性)。
  6. 错误处理strerrorerrno的配合使用,理解错误码的意义。

掌握这些函数是字符串处理的基础,需重点关注函数的边界条件(如\0的处理、空间大小检查)和返回值特性,避免常见错误。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐