You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
| ^~~~~~~~

核心问题与错误分析

  1. 返回局部变量地址:strfinal是函数内的局部数组,函数执行完毕后其所在栈内存会被回收,返回该地址属于未定义行为,这就是警告的根源。
  2. 字符串溢出:word1大小为20,拼接word2后总长度超过20,会触发数组越界,导致内存错误。
  3. 元音替换不完整:仅检查了索引0的字符,且只处理大写元音,未遍历整个字符串,也没覆盖小写情况。
  4. 变量类型错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:10:30