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

CS50 n0 v0w3ls练习:字符数组返回空值问题求助

CS50 n0 v0w3ls 练习输出为空问题

我在完成CS50的n0 v0w3ls练习时遇到了问题,无法得到非空输出。我在string/char类型转换以及为输出字符赋值的过程中完全混乱,试了多种组合还是搞不懂差异在哪。现在程序在调试器里看似正常,但输出是空的,求帮忙。

我的目标是把元音替换成数字,思路是:

  • 将输入作为string处理
  • 遍历该string的每个字符
  • 若字符是元音则在输出字符串中替换为对应数字,否则保持原样
  • 返回输出字符数组/string?

我尝试了两段代码:

第一段代码:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

char replace(string input);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Incorrect number of arguments\n");
        return 1;
    }
    else
    {
        printf("%c\n", replace(argv[1]));
    }

}

char replace(string input)
{
    int n = strlen(input);
    //n+1 as I read the last char should be a '\0' to be recognised as a string
    char s[n+1];

    for (int i = 0; i < n; i++)
    {
        //printf("%c\n", input[i]);
        switch (input[i])
        {
            case 97:
                s[i] = '6' ;
                break;
            case 101:
                s[i] = '3';
                break;
            case 105:
                s[i] = '1';
                break;
            case 111:
                s[i] = '0';
                break;
            default:
                s[i] = input[i];
                break;
        }
    }
    return s[n];
}

第二段代码:

// Write a function to replace vowels with numbers
// Get practice with strings
// Get practice with command line
// Get practice with switch

#include <cs50.h>
#include <stdio.h>
#include <string.h>

string replace(string input);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Incorrect number of arguments\n");
        return 1;
    }
    else
    {
        printf("%s\n", replace(argv[1]));
    }

}

string replace(string input)
{
    int n = strlen(input);
    string s[n+1];

    for (int i = 0; i < n; i++)
    {
        //printf("%c\n", input[i]);
        switch (input[i])
        {
            case 'a':
                s[i] = "6" ;
                break;
            case 'e':
                s[i] = "3";
                break;
            case 'i':
                s[i] = "1";
                break;
            case 'o':
                s[i] = "0";
                break;
            default:
                s[i] = &input[i];
                break;
        }
    }
    s[n+1] = "\0";
    return s[n];
}

问题分析

两段代码都存在核心逻辑错误:

  1. 第一段代码问题:

    • 函数返回类型定义为char,但实际需要返回完整字符串,类型完全不匹配。
    • 最终返回的s[n]是未初始化的数组末尾位置(循环只处理到i<n,s[n]默认值为'\0'),输出空字符自然看不到内容。
    • 就算修改返回类型,局部数组s在函数结束后会被栈内存回收,返回其地址会导致未定义行为。
  2. 第二段代码问题:

    • string s[n+1]定义的是字符串数组(每个元素是char*),而非存储结果的单个字符数组,完全偏离需求。
    • 赋值时用s[i] = "6"是把字符串字面量的地址存入数组元素,最后返回的s[n]未被赋值,必然为空。
    • 数组越界:s[n+1] = "\0",数组长度为n+1,合法索引范围是0~n,访问n+1会触发越界错误。

修正后的代码

按照你的思路,正确实现需要用堆内存分配存储结果,确保返回后内存有效:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

string replace(string input);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Incorrect number of arguments\n");
        return 1;
    }
    else
    {
        string result = replace(argv[1]);
        printf("%s\n", result);
        free(result); // 释放堆内存,避免泄漏
        return 0;
    }
}

string replace(string input)
{
    int n = strlen(input);
    // 分配n+1字节内存,包含字符串终止符位置
    string s = malloc(n + 1);
    if (s == NULL)
    {
        return NULL;
    }

    for (int i = 0; i < n; i++)
    {
        switch (input[i])
        {
            case 'a':
            case 'A': // 兼容大写元音
                s[i] = '6';
                break;
            case 'e':
            case 'E':
                s[i] = '3';
                break;
            case 'i':
            case 'I':
                s[i] = '1';
                break;
            case 'o':
            case 'O':
                s[i] = '0';
                break;
            default:
                s[i] = input[i];
                break;
        }
    }
    s[n] = '\0'; // 添加字符串终止符
    return s;
}

关键要点

  • CS50的string本质是char*,返回字符串时函数类型必须为string或char*。
  • 局部数组不能作为返回值,必须用malloc在堆上分配内存,使用完毕后记得用free释放。
  • 字符串必须以'\0'结尾,否则printf("%s")无法正确识别。
  • 可以扩展处理大写元音,提升程序兼容性。

内容的提问来源于stack exchange,提问作者soge king

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:20:20