C语言字符串拼接与元音替换实现及函数返回字符串问题求助
C字符串拼接与元音替换问题修正
原问题与代码
我需要编写一个C程序,声明两个自定义内容的字符串,将它们拼接成第三个字符串,并将第三个字符串中的每个元音替换为星号*。目前遇到的核心难题是如何从接收两个字符串的函数中返回字符串,以下是我的代码:
#include <stdio.h> #include <string.h> const char* concatvow (char *str1, char *str2); int main() { char word1[20]="One plus one "; char word2[20]="eqauls two"; char *word3[20]; concatvow(word1, word2); printf("%s", *word3); return 0; } const char* concatvow (char *str1, char *str2){ char strfinal[20]; int i=0; strcat(str1, str2); strcpy(strfinal, str1); if(strfinal[i]==65 || strfinal[i]==69 || strfinal[i]==73 || strfinal[i]==79 || strfinal[i]==85) { strfinal[i]='*'; } return strfinal; }
编译时出现警告:
main.c: In function ‘concatvow’:
main.c:33:8: warning: function returns address of local variable [-Wreturn-local-addr]
33 | return strfinal;
| ^~~~~~~~
核心问题与错误分析
- 返回局部变量地址:
strfinal是函数内的局部数组,函数执行完毕后其所在栈内存会被回收,返回该地址属于未定义行为,这就是警告的根源。 - 字符串溢出:
word1大小为20,拼接word2后总长度超过20,会触发数组越界,导致内存错误。 - 元音替换不完整:仅检查了索引0的字符,且只处理大写元音,未遍历整个字符串,也没覆盖小写情况。
- 变量类型错误:
char *word3[20]是指针数组,不是存储字符串的字符数组,且未接收函数返回值,直接打印*word3会读取无效内存。
修正方案
方案1:调用方提供目标缓冲区(推荐,无内存泄漏风险)
由调用方提前分配足够大的缓冲区,函数直接在该缓冲区上完成拼接和替换操作:
#include <stdio.h> #include <string.h> #include <ctype.h> // dest:调用方提供的目标缓冲区,需足够容纳两个字符串拼接后的内容 char* concat_replace_vowels(char *dest, const char *str1, const char *str2) { // 拼接两个字符串到目标缓冲区 strcpy(dest, str1); strcat(dest, str2); // 遍历字符串,替换所有元音(大小写均处理) char *ptr = dest; while (*ptr != '\0') { char upper_c = toupper(*ptr); if (upper_c == 'A' || upper_c == 'E' || upper_c == 'I' || upper_c == 'O' || upper_c == 'U') { *ptr = '*'; } ptr++; } return dest; } int main() { const char word1[] = "One plus one "; const char word2[] = "equals two"; // 计算所需缓冲区大小:两个字符串长度之和 + 1(字符串终止符) char word3[strlen(word1) + strlen(word2) + 1]; concat_replace_vowels(word3, word1, word2); printf("%s\n", word3); return 0; }
方案2:函数内部动态分配内存
函数通过malloc分配内存存储结果,调用方使用完毕后需手动释放内存:
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> char* concat_replace_vowels(const char *str1, const char *str2) { size_t len1 = strlen(str1); size_t len2 = strlen(str2); // 分配足够内存:总长度 + 1 char *dest = malloc(len1 + len2 + 1); if (dest == NULL) { perror("内存分配失败"); return NULL; } // 拼接字符串 strcpy(dest, str1); strcat(dest, str2); // 替换元音 char *ptr = dest; while (*ptr != '\0') { char upper_c = toupper(*ptr); if (upper_c == 'A' || upper_c == 'E' || upper_c == 'I' || upper_c == 'O' || upper_c == 'U') { *ptr = '*'; } ptr++; } return dest; } int main() { const char word1[] = "One plus one "; const char word2[] = "equals two"; char *word3 = concat_replace_vowels(word1, word2); if (word3 == NULL) { return 1; } printf("%s\n", word3); // 释放动态分配的内存,避免内存泄漏 free(word3); return 0; }
关键说明
- 永远不要返回局部变量的地址,局部变量的生命周期仅限于函数执行期间。
- 字符串操作必须确保缓冲区足够大,避免数组越界。
- 处理字符时可使用
toupper/tolower统一大小写,简化条件判断。
内容的提问来源于stack exchange,提问作者Firas Tabai
相关产品推荐
相关产品推荐

