如何不使用<string.h>库实现字符串中子串替换为'*'的C程序
实现需求:替换字符串中指定子串为单个'*'
首先咱们先明确需求的核心要点:
- 接收两个最多30字符的输入字符串,区分大小写,支持任意字符(数字、符号、标点都能处理)
- 不能使用
<string.h>库,必须手动逐个字符处理 - 把第一个字符串里所有匹配第二个字符串的子串,替换成单个
*字符,比如输入abchdfffchdchdtlchd和chd,要输出ab*fff**tl*
原代码的问题分析
你提供的代码存在几个关键逻辑问题,导致无法正确实现需求:
scanf格式符与缓冲区溢出风险:%[^\n ]会在空格或换行时停止读取,但未限制长度,可能导致缓冲区溢出;更稳妥的写法是%30[^\n]来约束输入长度fflush(stdin)的未定义行为:C标准里fflush仅对输出流有定义,对输入流使用属于未定义行为,不同编译器表现不同,应该用循环读取剩余字符的方式清空输入缓冲区- 替换逻辑错误:原代码的循环条件(逗号表达式导致提前终止)、匹配判断和字符串修改逻辑都存在问题,无法正确完成子串匹配与替换
正确的实现代码
下面是满足需求的完整实现,我在代码里加了详细注释:
#include <stdio.h> #define MAX 30 // 自定义函数:获取字符串长度(替代<string.h>的strlen) int getStrLength(const char *str) { int len = 0; while (str[len] != '\0' && len <= MAX) { len++; } return len; } // 自定义函数:安全清空输入缓冲区,替代fflush(stdin) void clearInputBuffer() { int c; while ((c = getchar()) != '\n' && c != EOF); } int main() { char str1[MAX + 1]; // 存储第一个输入字符串 char str2[MAX + 1]; // 存储要替换的子串 const char replace = '*'; int len1, len2; int i = 0, j = 0; char result[MAX * 2 + 1]; // 存储最终结果,预留足够空间避免溢出 // 输入第一个字符串 printf("Enter the first word (max 30 characters): "); scanf("%30[^\n]", str1); clearInputBuffer(); printf("You entered: %s\n", str1); len1 = getStrLength(str1); printf("Length: %d characters\n", len1); // 输入第二个字符串 printf("\nEnter the substring to replace with '*' (max 30 characters): "); scanf("%30[^\n]", str2); clearInputBuffer(); printf("You entered: %s\n", str2); len2 = getStrLength(str2); printf("Length: %d characters\n", len2); // 特殊情况处理:如果要替换的子串为空,直接输出原字符串 if (len2 == 0) { printf("\nResult: %s\n", str1); return 0; } // 遍历原字符串,寻找匹配子串并替换 while (i < len1) { int isMatch = 1; // 检查当前位置是否能匹配目标子串 for (int k = 0; k < len2; k++) { if (i + k >= len1 || str1[i + k] != str2[k]) { isMatch = 0; break; } } if (isMatch) { // 匹配成功,向结果数组添加一个'*' result[j++] = replace; i += len2; // 跳过原字符串中已匹配的子串长度 } else { // 不匹配,直接复制当前字符到结果数组 result[j++] = str1[i++]; } } result[j] = '\0'; // 给结果字符串添加结束符 // 输出最终结果 printf("\nResult: %s\n", result); return 0; }
代码说明
getStrLength函数:手动遍历字符串统计有效长度,完全替代<string.h>中的strlen功能clearInputBuffer函数:通过循环读取输入缓冲区的剩余字符,避免fflush(stdin)的跨编译器兼容性问题- 匹配与替换逻辑:
- 逐个遍历原字符串的每个位置,检查从当前位置开始是否能完整匹配目标子串
- 匹配成功则添加一个
*到结果数组,并跳过原字符串中对应子串的长度 - 匹配失败则直接复制当前字符到结果数组,继续下一个字符
- 缓冲区空间:结果数组设置为
MAX*2+1,确保即使原字符串全是匹配子串(比如原串是chdchd,子串是chd),替换后也有足够空间存储结果
测试示例
输入第一个字符串:abchdfffchdchdtlchd
输入第二个字符串:chd
输出结果:ab*fff**tl*,完全符合需求
内容的提问来源于stack exchange,提问作者ilMichigan
相关产品推荐
相关产品推荐

