Skip to content

C 标准库 - <ctype.h>

概述

<ctype.h> 头文件提供了一组用于测试和转换单个字符的函数。这些函数主要用于字符分类(判断字符类型)和字符转换(大小写转换)。

字符分类函数

isalnum()

c
int isalnum(int c);

检查字符是否为字母或数字。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char c1 = 'A';
    char c2 = '5';
    char c3 = '@';
    
    printf("%c 是字母或数字: %d\n", c1, isalnum(c1));
    printf("%c 是字母或数字: %d\n", c2, isalnum(c2));
    printf("%c 是字母或数字: %d\n", c3, isalnum(c3));
    
    return 0;
}

isalpha()

c
int isalpha(int c);

检查字符是否为字母(a-z, A-Z)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello World 123!";
    int letters = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isalpha(str[i])) {
            letters++;
        }
    }
    
    printf("字符串中的字母数量: %d\n", letters);
    return 0;
}

iscntrl()

c
int iscntrl(int c);

检查字符是否为控制字符(ASCII 0-31 和 127)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char c1 = '\n';
    char c2 = '\t';
    char c3 = 'A';
    
    printf("\\n 是控制字符: %d\n", iscntrl(c1));
    printf("\\t 是控制字符: %d\n", iscntrl(c2));
    printf("A 是控制字符: %d\n", iscntrl(c3));
    
    return 0;
}

isdigit()

c
int isdigit(int c);

检查字符是否为数字(0-9)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "abc123def456";
    int digits = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isdigit(str[i])) {
            digits++;
        }
    }
    
    printf("字符串中的数字数量: %d\n", digits);
    return 0;
}

isgraph()

c
int isgraph(int c);

检查字符是否为可打印字符(不包括空格)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char c1 = 'A';
    char c2 = ' ';
    char c3 = '\n';
    
    printf("A 是可打印字符: %d\n", isgraph(c1));
    printf("空格是可打印字符: %d\n", isgraph(c2));
    printf("\\n 是可打印字符: %d\n", isgraph(c3));
    
    return 0;
}

islower()

c
int islower(int c);

检查字符是否为小写字母(a-z)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello World";
    int lowercase = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (islower(str[i])) {
            lowercase++;
        }
    }
    
    printf("字符串中的小写字母数量: %d\n", lowercase);
    return 0;
}

isprint()

c
int isprint(int c);

检查字符是否为可打印字符(包括空格)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char c1 = 'A';
    char c2 = ' ';
    char c3 = '\n';
    
    printf("A 是可打印字符: %d\n", isprint(c1));
    printf("空格是可打印字符: %d\n", isprint(c2));
    printf("\\n 是可打印字符: %d\n", isprint(c3));
    
    return 0;
}

ispunct()

c
int ispunct(int c);

检查字符是否为标点符号。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello, World!";
    int punctuation = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (ispunct(str[i])) {
            punctuation++;
        }
    }
    
    printf("字符串中的标点符号数量: %d\n", punctuation);
    return 0;
}

isspace()

c
int isspace(int c);

检查字符是否为空白字符(空格、制表符、换行符等)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello\tWorld\nTest";
    int whitespace = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isspace(str[i])) {
            whitespace++;
        }
    }
    
    printf("字符串中的空白字符数量: %d\n", whitespace);
    return 0;
}

isupper()

c
int isupper(int c);

检查字符是否为大写字母(A-Z)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello World";
    int uppercase = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isupper(str[i])) {
            uppercase++;
        }
    }
    
    printf("字符串中的大写字母数量: %d\n", uppercase);
    return 0;
}

isxdigit()

c
int isxdigit(int c);

检查字符是否为十六进制数字(0-9, a-f, A-F)。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "0x1A2B3C";
    int hex_digits = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isxdigit(str[i])) {
            hex_digits++;
        }
    }
    
    printf("字符串中的十六进制数字数量: %d\n", hex_digits);
    return 0;
}

字符转换函数

tolower()

c
int tolower(int c);

将字符转换为小写字母。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello World";
    
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = tolower(str[i]);
    }
    
    printf("转换后的字符串: %s\n", str);
    return 0;
}

toupper()

c
int toupper(int c);

将字符转换为大写字母。

c
#include <stdio.h>
#include <ctype.h>

int main() {
    char str[] = "Hello World";
    
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = toupper(str[i]);
    }
    
    printf("转换后的字符串: %s\n", str);
    return 0;
}

实际应用示例

1. 密码强度检查

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

int check_password_strength(const char* password) {
    int has_upper = 0;
    int has_lower = 0;
    int has_digit = 0;
    int has_special = 0;
    int length = strlen(password);
    
    if (length < 8) {
        printf("密码长度至少需要 8 个字符\n");
        return 0;
    }
    
    for (int i = 0; password[i] != '\0'; i++) {
        if (isupper(password[i])) has_upper = 1;
        else if (islower(password[i])) has_lower = 1;
        else if (isdigit(password[i])) has_digit = 1;
        else if (ispunct(password[i])) has_special = 1;
    }
    
    if (!has_upper) {
        printf("密码需要包含大写字母\n");
        return 0;
    }
    if (!has_lower) {
        printf("密码需要包含小写字母\n");
        return 0;
    }
    if (!has_digit) {
        printf("密码需要包含数字\n");
        return 0;
    }
    if (!has_special) {
        printf("密码需要包含特殊字符\n");
        return 0;
    }
    
    printf("密码强度合格\n");
    return 1;
}

int main() {
    char password[100];
    
    printf("请输入密码: ");
    scanf("%s", password);
    
    check_password_strength(password);
    
    return 0;
}

2. 字符串统计

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

void analyze_string(const char* str) {
    int letters = 0;
    int digits = 0;
    int spaces = 0;
    int punctuation = 0;
    int others = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isalpha(str[i])) {
            letters++;
        } else if (isdigit(str[i])) {
            digits++;
        } else if (isspace(str[i])) {
            spaces++;
        } else if (ispunct(str[i])) {
            punctuation++;
        } else {
            others++;
        }
    }
    
    printf("字符串分析结果:\n");
    printf("字母: %d\n", letters);
    printf("数字: %d\n", digits);
    printf("空格: %d\n", spaces);
    printf("标点符号: %d\n", punctuation);
    printf("其他字符: %d\n", others);
}

int main() {
    char str[1000];
    
    printf("请输入字符串: ");
    fgets(str, sizeof(str), stdin);
    
    analyze_string(str);
    
    return 0;
}

3. 大小写转换工具

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

void to_uppercase(char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = toupper(str[i]);
    }
}

void to_lowercase(char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = tolower(str[i]);
    }
}

void toggle_case(char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        if (isupper(str[i])) {
            str[i] = tolower(str[i]);
        } else if (islower(str[i])) {
            str[i] = toupper(str[i]);
        }
    }
}

int main() {
    char str[1000];
    int choice;
    
    printf("请输入字符串: ");
    fgets(str, sizeof(str), stdin);
    
    printf("选择操作:\n");
    printf("1. 转换为大写\n");
    printf("2. 转换为小写\n");
    printf("3. 大小写互换\n");
    printf("请选择: ");
    scanf("%d", &choice);
    
    switch (choice) {
        case 1:
            to_uppercase(str);
            printf("转换结果: %s\n", str);
            break;
        case 2:
            to_lowercase(str);
            printf("转换结果: %s\n", str);
            break;
        case 3:
            toggle_case(str);
            printf("转换结果: %s\n", str);
            break;
        default:
            printf("无效的选择\n");
    }
    
    return 0;
}

4. 验证输入格式

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

int is_valid_email(const char* email) {
    int at_count = 0;
    int dot_count = 0;
    int length = strlen(email);
    
    if (length < 5) return 0;
    
    for (int i = 0; email[i] != '\0'; i++) {
        if (email[i] == '@') {
            at_count++;
        } else if (email[i] == '.') {
            dot_count++;
        }
    }
    
    return (at_count == 1 && dot_count >= 1);
}

int is_valid_phone(const char* phone) {
    int length = strlen(phone);
    
    if (length != 11) return 0;
    
    for (int i = 0; phone[i] != '\0'; i++) {
        if (!isdigit(phone[i])) {
            return 0;
        }
    }
    
    return 1;
}

int main() {
    char email[100];
    char phone[20];
    
    printf("请输入邮箱: ");
    scanf("%s", email);
    
    printf("请输入手机号: ");
    scanf("%s", phone);
    
    if (is_valid_email(email)) {
        printf("邮箱格式正确\n");
    } else {
        printf("邮箱格式错误\n");
    }
    
    if (is_valid_phone(phone)) {
        printf("手机号格式正确\n");
    } else {
        printf("手机号格式错误\n");
    }
    
    return 0;
}

5. 单词计数

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

int count_words(const char* str) {
    int count = 0;
    int in_word = 0;
    
    for (int i = 0; str[i] != '\0'; i++) {
        if (isalnum(str[i])) {
            if (!in_word) {
                count++;
                in_word = 1;
            }
        } else {
            in_word = 0;
        }
    }
    
    return count;
}

int main() {
    char str[1000];
    
    printf("请输入字符串: ");
    fgets(str, sizeof(str), stdin);
    
    printf("单词数量: %d\n", count_words(str));
    
    return 0;
}

注意事项

1. 参数类型

这些函数接受 int 类型的参数,但实际使用的是字符的 ASCII 值。

c
char c = 'A';
if (isalpha(c)) {  // 正确
    printf("是字母\n");
}

2. 返回值

这些函数返回非零值(真)或零(假),不一定是 1。

c
if (isdigit('5')) {  // 正确
    printf("是数字\n");
}

if (isdigit('5') == 1) {  // 不推荐,可能不等于 1
    printf("是数字\n");
}

3. 本地化

某些函数的行为可能受本地化设置影响。

c
#include <locale.h>
#include <ctype.h>

int main() {
    setlocale(LC_ALL, "");  // 设置本地化
    
    char c = 'é';
    printf("é 是字母: %d\n", isalpha(c));
    
    return 0;
}

性能考虑

对于大量字符处理,可以考虑以下优化:

c
// 使用查找表提高性能
static const int is_digit_table[256] = {
    ['0'] = 1, ['1'] = 1, ['2'] = 1, ['3'] = 1, ['4'] = 1,
    ['5'] = 1, ['6'] = 1, ['7'] = 1, ['8'] = 1, ['9'] = 1
};

int fast_isdigit(int c) {
    return (c >= 0 && c < 256) ? is_digit_table[c] : 0;
}

总结

<ctype.h> 提供的字符处理函数是 C 语言中处理字符的基础工具,它们具有以下特点:

  1. 简单易用 - 函数接口简单,易于理解和使用
  2. 高效可靠 - 标准库实现,经过充分测试和优化
  3. 广泛应用 - 在文本处理、输入验证、数据转换等场景中广泛使用

掌握这些函数的使用可以大大提高处理字符相关任务的效率。