删除字符数组中连续元音的C语言实现问题求助
问题分析与解决
看起来你的思路方向是对的,但处理连续元音时的字符串替换逻辑出了问题,导致程序异常。咱们一步步拆解问题:
你的代码里的核心问题
- 错误的字符串截断操作:当你找到第一个元音后,把
sir[i]替换成sir[pozitie],然后立刻把sir[pozitie]设为'\0'——这会直接截断整个字符串,后面的字符都无法被处理了。比如输入aabbbceee,第一次遇到a(i=0),pozitie会走到3(第一个b的位置),然后sir[0] = sir[3],sir[3] = '\0',此时字符串变成了bbbb\0...,后面的ceee直接被丢弃,完全不符合预期。 - scanf格式错误:
scanf("%[^ ]s", sir)是错误的写法,正确的读取不含换行符的字符串应该用scanf("%[^\n]", sir)。 - realloc的逻辑失效:虽然你计算了要删除的元音数量,但前面的字符串处理已经破坏了原字符串的结构,所以
realloc的长度计算即使正确,也无法得到正确结果。
修正方案:双指针法
最稳妥高效的方式是用双指针:一个指针(read)遍历原字符串,另一个指针(write)记录新字符串的写入位置。遇到非元音字符时,就把它复制到write的位置,然后write指针后移;遇到元音则跳过。这样不需要复杂的连续元音判断,自然就能处理所有情况。
修正后的代码如下:
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> bool isVowel(char a) { // 可选:加上大写元音的判断,适配更多场景 if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u' || a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U') return true; return false; } int main () { // C标准中main的返回类型必须是int,不能用void char* sir = (char*)calloc(256, sizeof(char)); if (sir == NULL) { // 检查内存分配是否成功,避免崩溃 perror("calloc failed"); return 1; } // 读取字符串,同时处理缓冲区的换行符 scanf("%[^\n]", sir); getchar(); // 吃掉输入后残留的换行符 int write = 0; int len = strlen(sir); for (int read = 0; read < len; ++read) { if (!isVowel(sir[read])) { sir[write] = sir[read]; write++; } } // 在新字符串末尾添加结束符 sir[write] = '\0'; // 重新分配内存到实际需要的大小(+1是为了存储'\0') char* temp = realloc(sir, write + 1); if (temp != NULL) { sir = temp; } printf("The string after I deleted the vowels: %s\n", sir); // 释放内存,避免内存泄漏 free(sir); return 0; }
关键改进点
- 双指针逻辑:
read指针逐个检查字符,write指针只记录非元音的位置,完美处理连续元音的情况——比如输入aabbbceee,read跳过前两个a,把三个b、一个c依次写入write的位置,自动跳过后面的三个e,最终得到bbbc。 - 规范代码结构:修正了
main函数的返回类型,符合C语言标准。 - 内存安全:增加了内存分配失败的检查,
realloc时用临时指针接收,避免原指针丢失;最后记得释放内存。 - 扩展性:
isVowel函数加上了大写元音的判断,如果你不需要可以直接删除这部分代码。
测试一下输入aabbbceee,输出就是你期望的bbbc啦!
内容的提问来源于stack exchange,提问作者Andrei Radu
相关产品推荐
相关产品推荐

