如何让C语言短信转换程序支持大小写输入并修复匹配问题提升安全性
C语言短信-文本双向转换程序问题修复方案
1. 实现大小写不敏感的匹配与转换
当前程序无法忽略大小写匹配,核心问题是匹配时严格区分字符大小写。解决思路是先将输入字符串统一转换为大写(或小写),再与预设的缩写/全写对照表匹配;若需要保留原输入的大小写风格,可在转换后针对性调整输出格式。
示例代码片段:
#include <ctype.h> #include <string.h> // 将字符串统一转为大写 void str_to_upper(char *str) { for (int i = 0; str[i] != '\0'; i++) { str[i] = toupper(str[i]); } } // 大小写不敏感的缩写匹配 char* match_abbrev(char *input) { char upper_input[256]; // 限制拷贝长度,避免溢出 strncpy(upper_input, input, sizeof(upper_input)-1); upper_input[sizeof(upper_input)-1] = '\0'; str_to_upper(upper_input); // 缩写-全写对照表 if (strcmp(upper_input, "WYM") == 0) { return "WHAT YOU MEAN"; } else if (strcmp(upper_input, "LOL") == 0) { return "LAUGH OUT LOUD"; } // 其他匹配项... return input; // 无匹配则返回原输入 }
2. 解决子串错误匹配问题
你遇到的WYM被拆成W(ON)+YM、LOL被拆成L(OST)+OL的问题,根源是程序做了子串替换而非整词匹配。必须确保只匹配独立单词,而非字符串中的局部子串。
整词匹配实现思路:
- 检查匹配位置的前一个字符是否为单词分隔符(空格、制表符、字符串开头)
- 检查匹配位置的后一个字符是否为单词分隔符(空格、标点、字符串结尾)
示例代码(以缩写转全写为例):
#include <stdio.h> #include <string.h> // 判断是否为单词分隔符 int is_word_sep(char c) { return c == ' ' || c == '\t' || c == '\0' || c == '.' || c == '!' || c == '?'; } // 替换字符串中的整词缩写 void replace_abbrev(char *output, const char *input) { char temp[512]; strncpy(temp, input, sizeof(temp)-1); temp[sizeof(temp)-1] = '\0'; char *pos = temp; memset(output, 0, sizeof(output)); // 初始化输出缓冲区 while ((pos = strstr(pos, "WYM")) != NULL) { // 验证前后是否为分隔符,确保是独立单词 int prev_ok = (pos == temp) || is_word_sep(*(pos-1)); int next_ok = is_word_sep(*(pos+3)); // "WYM"长度为3 if (prev_ok && next_ok) { // 拼接替换内容 strncat(output, temp, pos - temp); strncat(output, "WHAT YOU MEAN", strlen("WHAT YOU MEAN")); pos += 3; // 跳过已匹配的缩写 temp += pos - temp; // 更新临时字符串起始位置 } else { pos += 1; // 不匹配则向后移动一位 } } strncat(output, temp, strlen(temp)); // 追加剩余未处理内容 }
3. 提升程序安全性
3.1 杜绝缓冲区溢出
- 禁止使用
gets(),改用fgets()读取输入并限制长度:
char input[256]; if (fgets(input, sizeof(input), stdin) != NULL) { // 去除fgets读取的换行符 input[strcspn(input, "\n")] = '\0'; }
- 用
strncpy()、strncat()替代strcpy()、strcat(),始终指定最大操作长度:
strncpy(dest, src, sizeof(dest)-1); dest[sizeof(dest)-1] = '\0'; // 强制添加字符串终止符
3.2 输入合法性校验
过滤用户输入中的非法控制字符,只允许可打印字符:
#include <ctype.h> int is_valid_input(char *str) { for (int i = 0; str[i] != '\0'; i++) { if (!isprint(str[i])) { return 0; } } return 1; }
3.3 避免未定义行为
- 确保所有字符串操作都以
'\0'结尾,禁止处理未终止的字符串; - 指针操作前先检查是否为
NULL,避免空指针解引用。
内容的提问来源于stack exchange,提问作者alvinl
相关产品推荐
相关产品推荐

