Appearance
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 语言中处理字符的基础工具,它们具有以下特点:
- 简单易用 - 函数接口简单,易于理解和使用
- 高效可靠 - 标准库实现,经过充分测试和优化
- 广泛应用 - 在文本处理、输入验证、数据转换等场景中广泛使用
掌握这些函数的使用可以大大提高处理字符相关任务的效率。