使用ncurses开发REPL时输出随机乱码,strcat拼接提示字符串异常
问题根因
bang数组未初始化:栈上申请的局部数组默认值是随机内存垃圾,strcat要求目标字符串必须以\0结尾才能正确找到拼接起始位置,未初始化的状态下strcat会读取到垃圾数据,就是你看到的乱码。strcat参数类型错误:strcat(bang, '\n')中第二个参数是字符'\n',但strcat要求第二个参数必须是合法的C字符串(以\0结尾的字符数组/指针),这里传字符会被解析为非法内存地址,触发未定义行为。wprintw参数顺序颠倒:ncurses的wprintw函数原型为int wprintw(WINDOW *win, const char *format, ...),你把提示字符串和窗口指针的顺序写反了,属于严重的调用错误。
修复方案
你询问的多字符串拼接问题,优先用snprintf实现,比多轮strcat安全,还能一次性完成拼接、自动规避缓冲区溢出风险,示例如下:
char bang[BANG_MAX]; // 按你的需求拼接换行、用户名、固定前缀、权限标识 int len = snprintf(bang, sizeof(bang), "\n%s @ wsh %c", uid, geteuid() == 0 ? '#' : '%'); // 可选校验缓冲区是否足够 if (len >= sizeof(bang)) { // 缓冲区不足的处理逻辑 }
如果一定要用strcat实现,需要调整为如下写法:
// 初始化数组全为0,保证第一个字符是\0,符合strcat的入参要求 char bang[BANG_MAX] = {0}; // 所有拼接参数都用双引号包裹的字符串,不能用单引号的字符 strcat(bang, "\n"); strcat(bang, uid); strcat(bang, " @ wsh "); strcat(bang, geteuid() == 0 ? "#" : "%");
最后修正wprintw的调用顺序:
if (wprintw(w, "%s", bang) == ERR) { // 原有错误处理逻辑不变
内容的提问来源于stack exchange,提问作者DistortedASD
相关产品推荐
相关产品推荐

