C语言项目:文本统计程序
C语言文本统计程序,功能如下:
- 统计文本中 总字符数
- 统计 英文字符数
- 统计 中文字符数
- 统计 空格数
- 统计 标点符号数
为了兼容中文,需要使用 UTF-8编码 的中文字符(每个中文一般占 3 个字节),或者 GBK编码(每个中文占 2 个字节)。这里我给出 UTF-8版本。
下面是示例代码(可统计中文、英文、空格和标点):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>int main() {FILE *fp;char filename[100];unsigned long total_chars = 0;unsigned long english_chars = 0;unsigned long chinese_chars = 0;unsigned long spaces = 0;unsigned long punctuation = 0;printf("请输入文本文件名: ");scanf("%s", filename);fp = fopen(filename, "r");if (!fp) {printf("无法打开文件 %s\n", filename);return 1;}int c;while ((c = fgetc(fp)) != EOF) {total_chars++;if (c <= 127) {// 英文字符、空格、标点if (isalpha(c)) english_chars++;else if (isspace(c)) spaces++;else punctuation++;} else {// 中文字符处理 (UTF-8一般3字节)chinese_chars++;// 跳过剩余字节if ((c & 0xE0) == 0xC0) fgetc(fp); // 2字节中文else if ((c & 0xF0) == 0xE0) { // 3字节中文fgetc(fp);fgetc(fp);} else if ((c & 0xF8) == 0xF0) { // 4字节字符fgetc(fp);fgetc(fp);fgetc(fp);}}}fclose(fp);printf("\n===== 文本统计结果 =====\n");printf("总字符数: %lu\n", total_chars);printf("英文字符数: %lu\n", english_chars);printf("中文字符数: %lu\n", chinese_chars);printf("空格数: %lu\n", spaces);printf("标点符号数: %lu\n", punctuation);return 0;
}
⚙️ 使用说明
- 将程序保存为
text_stat.c
- 编译运行:
gcc -o text_stat text_stat.c
./text_stat
- 输入文本文件名,例如
test.txt
- 输出统计信息,包括中文、英文、空格和标点
1️⃣ UTF-8 编码基础
UTF-8 是变长编码,用 1~4 个字节表示一个字符:
字节数 | 二进制模式 | 范围 |
---|---|---|
1 | 0xxxxxxx | ASCII 0~127 |
2 | 110xxxxx 10xxxxxx | U+0080~U+07FF |
3 | 1110xxxx 10xxxxxx 10xxxxxx | U+0800~U+FFFF |
4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | U+10000~U+10FFFF |
x
是字符的实际二进制位- 第一个字节的高位标记 字节长度,后续字节都以
10xxxxxx
开头
2️⃣ 为什么用 0xC0、0xE0、0xF0、0xF8
在代码里判断一个字符是几字节中文:
if ((c & 0xE0) == 0xC0) // 2字节
if ((c & 0xF0) == 0xE0) // 3字节
if ((c & 0xF8) == 0xF0) // 4字节
- 0xC0 = 11000000(二进制) → 判断是否是 2 字节字符
- 0xE0 = 11100000(二进制) → 判断是否是 3 字节字符
- 0xF0 = 11110000(二进制) → 判断是否是 4 字节字符
- 0xF8 = 11111000(二进制) → 理论上 UTF-8 最多 4 字节,5~6 字节已废弃
逻辑解释:
(c & 0xF0) == 0xE0
c & 0xF0
→ 取前 4 位- 3 字节中文的首字节前 4 位固定为 1110
- 所以如果等于 0xE0(1110 0000),就是 3 字节中文
3️⃣ 总结记忆
UTF-8字节数 | 首字节二进制 | 十六进制 | 注释 |
---|---|---|---|
1 | 0xxxxxxx | 0x00~0x7F | ASCII |
2 | 110xxxxx | 0xC0~0xDF | 拉丁扩展 |
3 | 1110xxxx | 0xE0~0xEF | 常用中文 |
4 | 11110xxx | 0xF0~0xF7 | 较生僻字符 |
5~6 | 111110xx / 1111110x | 0xF8~0xFD | 已废弃 |
UTF-8 字节长度判定示意图
首字节范围 | 二进制模式 | 字节长度 | 说明 |
---|---|---|---|
0x00 ~ 0x7F | 0xxxxxxx | 1 | ASCII 英文字符 |
0xC0 ~ 0xDF | 110xxxxx | 2 | 拉丁文/少量扩展 |
0xE0 ~ 0xEF | 1110xxxx | 3 | 常用中文汉字 |
0xF0 ~ 0xF7 | 11110xxx | 4 | 生僻汉字或表情 |
0xF8 ~ 0xFB | 111110xx | 5 | 已废弃 |
0xFC ~ 0xFD | 1111110x | 6 | 已废弃 |
UTF-8 多字节字符结构示意:
字节数 | 首字节 | 后续字节 |
---|---|---|
1 | 0xxxxxxx | - |
2 | 110xxxxx | 10xxxxxx |
3 | 1110xxxx | 10xxxxxx 10xxxxxx |
4 | 11110xxx | 10xxxxxx 10xxxxxx 10xxxxxx |
示例:
1️⃣ 英文字符 ‘A’ → 0x41 → 1 字节
2️⃣ 中文 ‘你’ → 0xE4 0xBD 0xA0 → 3 字节
3️⃣ 表情 ‘😊’ → 0xF0 0x9F 0x98 0x8A → 4 字节
✅ 总结记忆法:
- 0xxxxxxx → 1 字节:英文
- 110xxxxx → 2 字节:少量扩展字符
- 1110xxxx → 3 字节:常用中文
- 11110xxx → 4 字节:生僻汉字或表情
这些 0xC0、0xE0、0xF0 本质上是 UTF-8 首字节掩码,用来判断当前字节属于几字节字符,从而跳过剩余字节统计总字符数。