实现Mini-T9时使用二维数组与printf出现乱码问题求助
代码问题分析与修正
核心错误点
strlen(argv)用法错误:argv是指针数组,不能直接用strlen计算输入字符串长度,应该用strlen(argv[1]),且必须先检查argc >= 2,避免访问空指针。- 数组赋值方式错误:
letters[i][4] = 'a', 'b', 'c', '\0';是逗号表达式,仅会将最后一个值'\0'赋值给越界的下标4(数组letters[i]的有效下标是0-3),正确做法是用strcpy或逐个赋值字符到对应下标。 - 变量名拼写不一致:部分case里错误使用
letter(少了s),应该统一为letters。 - 标点符号错误:多处用
.代替逗号分隔字符(比如'e'. 'f'),导致编译错误。 - Switch缺少break:每个case执行后没有
break,会触发后续所有case的代码,导致赋值混乱。 - 调试循环逻辑错误:循环变量
e从1开始(应该从0),且用<=导致越界访问;子数组循环j同样用<=,超出有效下标范围。 - 局部数组未初始化:栈上的
letters数组未初始化,未赋值的位置会残留垃圾值,导致输出乱码。
修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { // 检查输入参数是否合法 if (argc < 2) { printf("请输入数字串作为参数,例如:./t9 23\n"); return 1; } int input_len = strlen(argv[1]); // 每个数字对应最多4个字母,加终止符,所以每个子数组大小为4 char letters[input_len][4]; // 初始化数组,避免垃圾值 memset(letters, 0, sizeof(letters)); for (int i = 0; i < input_len; i++) { switch(argv[1][i]) { case '2': strcpy(letters[i], "abc"); break; case '3': strcpy(letters[i], "def"); break; case '4': strcpy(letters[i], "ghi"); break; case '5': strcpy(letters[i], "jkl"); break; case '6': strcpy(letters[i], "mno"); break; case '7': strcpy(letters[i], "pqrs"); break; case '8': strcpy(letters[i], "tuv"); break; case '9': strcpy(letters[i], "wxyz"); break; default: printf("无效数字:%c\n", argv[1][i]); return 1; } } // 调试输出 for (int e = 0; e < input_len; e++) { printf("Letters[%d]: ", e); for (int j = 0; j < 4 && letters[e][j] != '\0'; j++) { printf("%c ", letters[e][j]); } printf("\n"); } // 后续可以添加读取姓名列表并匹配的逻辑 return 0; }
额外说明
- 添加了参数合法性检查,避免程序因无输入崩溃。
- 用
memset初始化数组,清除栈上的垃圾值。 - 调试输出改为按行打印每个数字对应的字母,更直观。
- 后续实现姓名匹配时,需要遍历姓名列表,检查每个姓名的每个字符是否对应输入数字组中的字母集合(比如姓名第一个字符必须是
letters[0]中的某一个,第二个字符必须是letters[1]中的某一个,以此类推)。
内容的提问来源于stack exchange,提问作者nazarrer
相关产品推荐
相关产品推荐

