C 语言实例 – 字符串中各种字符计算(一文讲透)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
前言
在编程的世界中,字符串(String)如同一条承载信息的河流,而字符(Character)则是这条河中的每一滴水珠。对于开发者而言,如何精准地统计字符串中字母、数字、空格、标点等不同类别的字符数量,既是基础技能,也是解决复杂问题的基石。本文将以“C 语言实例 – 字符串中各种字符计算”为主题,通过循序渐进的方式,结合代码示例和实际案例,帮助读者掌握这一技能的核心逻辑与实现方法。
字符串与字符的“分拣站”:基本概念
在开始编程之前,我们需要明确几个关键概念:
- 字符串的存储方式:在 C 语言中,字符串本质上是一个以空字符(
'\0'
)结尾的字符数组。例如,字符串"Hello"
实际上存储为'H'
,'e'
,'l'
,'l'
,'o'
,'\0'
。 - 字符分类:根据 ASCII 码表,字符可以分为字母(
A-Z
/a-z
)、数字(0-9
)、空格(' '
)、标点符号(如','
,'.'
)等。 - 统计需求:常见的统计目标包括:
- 统计字母总数(区分大小写或合并统计)
- 统计数字字符数量
- 统计空格与标点符号的数量
- 区分其他特殊字符(如
@
,#
,$
等)
形象比喻:可以将字符串视为一条项链,每个字符是项链上的珠子,而我们的任务是将这些珠子按照材质(字母、数字等)分类放入不同的“抽屉”中。
实例一:统计字母、数字与空格
代码示例
#include <stdio.h>
#include <ctype.h> // 包含字符处理函数
int main() {
char str[] = "Hello World! 123"; // 示例字符串
int letters = 0, digits = 0, spaces = 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++;
}
}
printf("Letters: %d\nDigits: %d\nSpaces: %d\n", letters, digits, spaces);
return 0;
}
关键知识点解析
ctype.h
头文件:提供了isalpha()
,isdigit()
,isspace()
等函数,用于快速判断字符类型。- 循环终止条件:
str[i] != '\0'
确保循环在字符串结尾时停止。 - 统计逻辑:通过嵌套的
if-else
结构,逐个字符分类计数。
输出结果:
Letters: 10
Digits: 3
Spaces: 2
进阶实例:区分大小写字母与扩展统计
需求升级
假设我们需要进一步区分大写字母和小写字母,同时统计标点符号的数量。
代码示例
#include <stdio.h>
#include <ctype.h>
int main() {
char str[] = "C语言实例 – 字符串中各种字符计算!"; // 包含中文与特殊字符
int uppercase = 0, lowercase = 0, digits = 0;
int spaces = 0, punctuation = 0, others = 0;
for(int i = 0; str[i] != '\0'; i++) {
char current = str[i];
if(isupper(current)) {
uppercase++;
} else if(islower(current)) {
lowercase++;
} else if(isdigit(current)) {
digits++;
} else if(isspace(current)) {
spaces++;
} else if(strchr(".,;:!?", current)) { // 自定义标点符号列表
punctuation++;
} else {
others++;
}
}
printf("Uppercase: %d\nLowercase: %d\nDigits: %d\n", uppercase, lowercase, digits);
printf("Spaces: %d\nPunctuation: %d\nOthers: %d\n", spaces, punctuation, others);
return 0;
}
知识点扩展
- 区分大小写:
isupper()
和islower()
函数分别判断字符是否为大写或小写字母。 - 自定义标点符号:通过
strchr()
函数检查字符是否在预设的标点列表中。 - 处理非 ASCII 字符:当字符串包含中文或特殊符号时,
others
变量会统计这些字符。
输出结果(以中文字符为例):
Uppercase: 0
Lowercase: 0
Digits: 0
Spaces: 2
Punctuation: 1
Others: 22
优化与陷阱:常见问题与解决方案
陷阱一:忘记空字符的终止条件
错误代码示例:
for(int i = 0; i < 10; i++) { ... } // 固定循环次数可能导致越界
解决方案:始终使用 str[i] != '\0'
或 strlen()
函数控制循环范围。
陷阱二:未处理多字节字符
当字符串包含中文或 Unicode 字符时,strlen()
和逐字符遍历可能失效。此时需要:
- 使用宽字符函数(如
wchar_t
)或 UTF-8 解析库。 - 或者仅统计可见字符,忽略编码细节。
优化技巧
- 预分配计数器:使用结构体(
struct
)或数组管理统计结果,提高代码可读性。 - 函数封装:将统计逻辑封装为独立函数,例如:
void count_characters(const char *str, int *counts) { ... }
实战案例:密码强度分析器
需求
设计一个程序,统计用户输入的密码中包含的字符类别,以评估密码强度。
要求统计:
- 大写字母、小写字母、数字、特殊字符(如
!
,@
,#
)的数量 - 输出密码强度等级
代码实现
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MIN_LENGTH 8 // 最小密码长度
int main() {
char password[100];
printf("请输入密码:");
fgets(password, sizeof(password), stdin);
int uppercase = 0, lowercase = 0, digits = 0, special = 0;
const char *special_chars = "!@#$%^&*()";
// 移除fgets读取的换行符
password[strcspn(password, "\n")] = '\0';
for(int i = 0; password[i] != '\0'; i++) {
char c = password[i];
if(isupper(c)) uppercase++;
else if(islower(c)) lowercase++;
else if(isdigit(c)) digits++;
else if(strchr(special_chars, c)) special++;
}
int score = 0;
if(uppercase > 0) score += 2;
if(lowercase > 0) score += 2;
if(digits > 0) score += 2;
if(special > 0) score += 3;
if(strlen(password) >= MIN_LENGTH) score += 3;
printf("\n密码强度分析:\n");
printf("大写字母: %d\n小写字母: %d\n数字: %d\n特殊字符: %d\n", uppercase, lowercase, digits, special);
printf("总分: %d/12\n", score);
if(score >= 9) printf("密码强度:强\n");
else if(score >= 6) printf("密码强度:中等\n");
else printf("密码强度:弱\n");
return 0;
}
输出示例
请输入密码:HelloWorld123!
密码强度分析:
大写字母: 2
小写字母: 8
数字: 3
特殊字符: 1
总分: 12/12
密码强度:强
结论
通过本文的实例与代码分析,我们掌握了以下核心能力:
- 基础统计:利用
ctype.h
函数快速分类字母、数字与空格。 - 进阶需求:区分大小写字母、自定义标点符号的统计方法。
- 优化与陷阱:避免常见错误,并学会封装统计逻辑以提升代码复用性。
- 实战应用:通过密码强度分析器案例,理解如何将统计功能融入实际项目。
字符串处理是编程中的“基本功”,而字符分类统计则是这一基本功的典型应用场景。希望读者通过本文不仅能掌握代码实现,更能培养“以小见大”的思维模式——从简单问题出发,逐步构建解决复杂问题的能力。
下一步行动建议:
- 尝试修改代码,统计字符串中的中文字符数量。
- 设计一个程序,统计用户输入的文本中每个单词的出现次数。
- 使用
strtok()
函数分割字符串,并统计标点符号的具体类型(如感叹号、问号等)。
通过持续练习与实践,你将逐步成为字符串处理的“分拣大师”!