首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言字符大小寫轉換:標準庫函數、ASCII碼位運算與完整實現

     編輯:C 語言問答

標準庫函數法 (推薦,可移植、處理本地化)

#include <stdio.h>
#include <ctype.h>  // 核心頭文件
#include <string.h>

int main() {
    char str[] = "Hello World! 123";
    printf("原始: %s\n", str);
    
    // 大寫轉小寫
    for (int i = 0; str[i]; i++) {
        str[i] = tolower(str[i]);
    }
    printf("全小寫: %s\n", str);
    
    // 小寫轉大寫
    for (int i = 0; str[i]; i++) {
        str[i] = toupper(str[i]);
    }
    printf("全大寫: %s\n", str);
    
    // 大小寫反轉
    for (int i = 0; str[i]; i++) {
        if (islower(str[i])) str[i] = toupper(str[i]);
        else if (isupper(str[i])) str[i] = tolower(str[i]);
    }
    printf("大小寫反轉: %s\n", str);
    
    return 0;
}

<ctype.h> 核心函數表

函數功能返回值
isupper(c)判斷大寫字母非0(真) / 0(假)
islower(c)判斷小寫字母非0 / 0
isalpha(c)判斷字母非0 / 0
isdigit(c)判斷數字字符非0 / 0
isalnum(c)判斷字母或數字非0 / 0
toupper(c)轉大寫轉換後字符 (int)
tolower(c)轉小寫轉換後字符 (int)
isprint(c)可打印字符非0 / 0
isspace(c)空白字符 (空格、\t、\n等)非0 / 0

ASCII 碼位運算法 (高性能、無庫依賴、教學理解)

// 大寫轉小寫:第5位置1 (或加 32)
char to_lower_ascii(char c) {
    if (c >= 'A' && c <= 'Z') return c + 32;  // 或 c | 0x20
    return c;
}

// 小寫轉大寫:第5位清0 (或減 32)
char to_upper_ascii(char c) {
    if (c >= 'a' && c <= 'z') return c - 32;  // 或 c & 0xDF
    return c;
}

// 大小寫反轉:第5位取反
char toggle_case_ascii(char c) {
    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) 
        return c ^ 0x20;  // XOR 32 翻轉第6位
    return c;
}

位運算原理圖解

'A' = 0x41 = 0100 0001
'a' = 0x61 = 0110 0001
       ↑
     第6位 (值32) 差異

c | 0x20  → 強制第6位為1 (轉小寫)
c & 0xDF  → 強制第6位為0 (轉大寫)  (0xDF = 1101 1111)
c ^ 0x20  → 翻轉第6位 (大小寫反轉)

完整工具函數庫實現

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

// 就地轉換:全大寫
void str_toupper(char *str) {
    for (; *str; str++) *str = toupper(*str);
}

// 就地轉換:全小寫
void str_tolower(char *str) {
    for (; *str; str++) *str = tolower(*str);
}

// 就地轉換:大小寫反轉
void str_toggle_case(char *str) {
    for (; *str; str++) {
        if (islower(*str)) *str = toupper(*str);
        else if (isupper(*str)) *str = tolower(*str);
    }
}

// 複製並轉換:返回目標緩衝區指針
char* str_copy_toupper(char *dest, const char *src) {
    char *p = dest;
    while (*src) *p++ = toupper(*src++);
    *p = '\0';
    return dest;
}

// 忽略大小寫字符串比較
int strcasecmp(const char *s1, const char *s2) {
    while (*s1 && *s2) {
        int c1 = toupper(*s1++);
        int c2 = toupper(*s2++);
        if (c1 != c2) return c1 - c2;
    }
    return toupper(*s1) - toupper(*s2);
}

本地化與多字節字符陷阱

⚠️ 重要限制

  • ctype.h 函數僅保證處理 **ASCII 字符 (0-127)** 和當前 locale 的單字節字符
  • **UTF-8 中文、日文等多字節字符不可直接用此函數處理**
  • 中文大小寫轉換無意義 (漢字無大小寫)
  • 處理 Unicode 需使用 wchar.h 寬字符函數 (towupper, towlower) 或 ICU 庫

性能對比測試

#include <time.h>
#include <ctype.h>

void benchmark() {
    const int N = 10000000;
    char *buf = malloc(N);
    memset(buf, 'a', N);
    
    clock_t start = clock();
    for (int i = 0; i < N; i++) buf[i] = toupper(buf[i]);
    printf("toupper(): %.3f ms\n", (clock()-start)*1000.0/CLOCKS_PER_SEC);
    
    memset(buf, 'a', N);
    start = clock();
    for (int i = 0; i < N; i++) buf[i] = (buf[i] >= 'a' && buf[i] <= 'z') ? buf[i] - 32 : buf[i];
    printf("ASCII bitwise: %.3f ms\n", (clock()-start)*1000.0/CLOCKS_PER_SEC);
    
    free(buf);
}

典型結果:位運算快 2-5 倍,但標準庫函數處理邊界情況更安全。

最佳實踐建議

  1. 業務代碼:優先使用 ctype.h,可讀性強、可移植、自動處理 locale
  2. 高性能/嵌入式:確認僅處理 ASCII 時,可用位運算優化
  3. 字符串處理:封裝通用工具函數,統一錯誤處理
  4. 跨平台:避免假設字符編碼,使用標準庫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved