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]; }
问题分析
两段代码都存在核心逻辑错误:
第一段代码问题:
- 函数返回类型定义为
char,但实际需要返回完整字符串,类型完全不匹配。 - 最终返回的
s[n]是未初始化的数组末尾位置(循环只处理到i<n,s[n]默认值为'\0'),输出空字符自然看不到内容。 - 就算修改返回类型,局部数组
s在函数结束后会被栈内存回收,返回其地址会导致未定义行为。
- 函数返回类型定义为
第二段代码问题:
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
相关产品推荐
相关产品推荐

