在 <string.h> 头文件中,几个相关的字符串比较函数:

函数 功能描述
strcmp(str1, str2) 区分大小写的字符串比较
strncmp(str1, str2, n) 比较前n个字符,区分大小写
stricmp(str1, str2) 不区分大小写的比较(Windows)
strcasecmp(str1, str2) 不区分大小写的比较(Linux)

一、strcmp函数

#include <stdio.h>
#include <string.h>  // strcmp 的头文件

int main() {
    char str1[] = "hello";
    char str2[] = "hello";
    char str3[] = "world";
    
    // 比较字符串
    int result1 = strcmp(str1, str2);  // 返回 0 (相等)
    int result2 = strcmp(str1, str3);  // 返回负数 (str1 < str3)
    int result3 = strcmp(str3, str1);  // 返回正数 (str3 > str1)
    
    printf("str1 vs str2: %d\n", result1);
    printf("str1 vs str3: %d\n", result2);
    printf("str3 vs str1: %d\n", result3);
    
    // 实际应用中的常见用法
    if (strcmp(str1, str2) == 0) {
        printf("字符串相等\n");
    } else {
        printf("字符串不相等\n");
    }
    
    return 0;
}

二、strncmp函数

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

int main() {
    char str1[] = "hello world";
    char str2[] = "hello there";
    
    // 只比较前5个字符
    if (strncmp(str1, str2, 5) == 0) {
        printf("前5个字符相同\n");
    } else {
        printf("前5个字符不同\n");
    }
    
    return 0;
}

三、不区分大小写的比较

stricmp 与strcasecmp的兼容性问题

1. stricmp 是 Windows 特有的

  • Windows 平台:stricmp 在 <string.h> 中可用

  • Linux/Unix 平台:使用 strcasecmp

  • 标准 C 库:实际上都没有标准化这两个函数

2. STM32 开发中的情况

在STM32开发中,使用的通常是标准C库或newlib等嵌入式C库,这些库可能不支持 stricmp

3.STM32 中的解决方案自己实现不区分大小写的比较

方法一:

#include <ctype.h>
#include <string.h>

int my_stricmp(const char *str1, const char *str2)
{
    while (*str1 && *str2)
    {
        int diff = tolower((unsigned char)*str1) - 
                   tolower((unsigned char)*str2);
        if (diff != 0)
            return diff;
        str1++;
        str2++;
    }
    
    // 重要:这里要处理字符串长度不同的情况
    // 如果 str1 结束了,但 str2 还没结束
    // 或者 str2 结束了,但 str1 还没结束
    return tolower((unsigned char)*str1) - 
           tolower((unsigned char)*str2);
}

方法二

// 在STM32项目中的正确写法
#include "main.h"
#include <string.h>
#include <ctype.h>

// 自定义不区分大小写的比较函数
int string_case_insensitive_compare(const char *str1, const char *str2)
{
    while (*str1 && *str2)
    {
        char c1 = *str1;
        char c2 = *str2;
        
        // 转换为小写比较
        if (c1 >= 'A' && c1 <= 'Z')
            c1 += 32;  // 转换为小写
        if (c2 >= 'A' && c2 <= 'Z')
            c2 += 32;  // 转换为小写
            
        if (c1 != c2)
            return (int)c1 - (int)c2;
            
        str1++;
        str2++;
    }
    return *str1 - *str2;
}

// 使用示例
void compare_strings(void)
{
    const char *cmd = "START";
    if (string_case_insensitive_compare(cmd, "start") == 0)
    {
        printf("命令匹配\n");
    }
}

三、tolower函数

tolower 是一个C标准库函数,用于将大写字母转换为小写字母。它定义在头文件 <ctype.h> 中。

基本用法。

#include <stdio.h>
#include <ctype.h>  // 必须包含这个头文件

int main() {
    char uppercase = 'A';
    char lowercase = 'a';
    char digit = '5';
    
    // 将大写字母转换为小写
    char result1 = tolower(uppercase);  // 'A' → 'a'
    char result2 = tolower(lowercase);  // 'a' → 'a' (不变)
    char result3 = tolower(digit);      // '5' → '5' (不变)
    
    printf("tolower('A') = %c\n", result1);
    printf("tolower('a') = %c\n", result2);
    printf("tolower('5') = %c\n", result3);
    
    return 0;
}

注意事项和常见问题

1. 类型转换问题

// 错误:直接使用 char 可能导致负数
char c = -1;
char result = tolower(c);  // 未定义行为

// 正确:先转换为 unsigned char
char c = -1;
char result = tolower((unsigned char)c);  // 安全

2. 返回值处理

tolower 返回的是 int 类型,不是 char

int ch = 'A';
int lower_ch = tolower(ch);  // 返回 int

// 如果需要 char 类型
char c = (char)tolower(ch);

3. STM32中的内存考虑

如果担心标准库占用内存,可以自己实现简化版:

// 简化版 tolower(只处理ASCII字符)
char simple_tolower(char c)
{
    if (c >= 'A' && c <= 'Z')
    {
        return c + ('a' - 'A');  // 转换为小写
    }
    return c;  // 其他字符不变
}

// 使用简化版的不区分大小写比较
int simple_stricmp(const char *s1, const char *s2)
{
    while (*s1 && *s2)
    {
        char c1 = simple_tolower(*s1);
        char c2 = simple_tolower(*s2);
        
        if (c1 != c2)
            return c1 - c2;
            
        s1++;
        s2++;
    }
    return simple_tolower(*s1) - simple_tolower(*s2);
}

4. 相关函数

函数 功能 头文件
tolower(c) 转小写 <ctype.h>
toupper(c) 转大写 <ctype.h>
isalpha(c) 是否是字母 <ctype.h>
isdigit(c) 是否是数字 <ctype.h>
isalnum(c) 是否是字母或数字 <ctype.h>

为什么返回 int 而不是 char

  1. EOF 的处理:<ctype.h> 中的函数需要能够返回 EOF(通常是 -1)

  2. 值范围:int 可以表示所有 unsigned char 值和 EOF

  3. 标准规定:C语言标准规定这些函数返回 int

5. 比较时直接使用 int

// 推荐:直接使用 int 比较
if (toupper((unsigned char)input_char) == 'A')
{
    // 执行操作
}

// 不推荐:转换为 char 再比较
char temp = toupper(input_char);
if (temp == 'A')  // 可能会有警告
{
    // ...
}

6. 字符串处理函数示例

#include <ctype.h>
#include <string.h>

// 将字符串转换为大写(正确处理类型)
void string_to_upper_proper(char *str)
{
    if (!str) return;
    
    while (*str)
    {
        // 三步:unsigned char → int → char
        *str = (char)toupper((unsigned char)*str);
        str++;
    }
}

// 不区分大小写的字符比较
int case_insensitive_char_compare(char c1, char c2)
{
    // 直接比较 int 值
    return toupper((unsigned char)c1) == toupper((unsigned char)c2);
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐