C++使用Match类输出足球赛结果时控制台出现奇怪乱码如何修复
足球比分程序乱码问题的根源与修复方案
核心问题根源
init_name函数中strncpy的长度参数错误:形参team1_name/team2_name是传参后退化的字符指针,sizeof(team1_name)获取的是指针本身的大小(32位环境下为4字节,64位为8字节),并非目标数组e1.name/e2.name的50字节长度。- 字符串未正确添加结束符
\0:32位环境下拷贝长度仅为4字节,最多拷贝"Team1"的前4个字符T/e/a/m,由于源字符串长度大于拷贝长度,strncpy不会自动补结束符。e1.name后续全是栈上的未初始化垃圾值,无\0标识字符串结束,cout输出时会持续读取内存直到遇到随机\0,因此出现大量╠类乱码。 print函数输出错误:最后输出的是e1.name而非e2.name,即使修复乱码也会重复显示主队名,无法正确展示客队名。- 原代码遗漏
strncpy所需的标准头文件<cstring>,部分老编译器会默认隐式包含,属于非标准兼容写法。
修复方案
- 修正
strncpy的长度参数为目标数组大小sizeof(e1.name)、sizeof(e2.name),并手动在拷贝后补\0避免越界读取。 - 修正
print函数的输出项,将末尾的e1.name改为e2.name。 - (可选规范优化)将非标准的
void main()改为C++标准要求的int main(),补充返回值。
修正后可正常运行的代码
#include <iostream> #include <cstring> #include <conio.h> using namespace std; class Match { private: typedef struct team { char name[50]; int goal; } team; team e1; team e2; public: void init_name(char team1_name[], char team2_name[]); void init_goal(int g1, int g2); void print(); }; void Match::init_name(char team1_name[], char team2_name[]) { strncpy(e1.name, team1_name, sizeof(e1.name) - 1); e1.name[sizeof(e1.name) - 1] = '\0'; strncpy(e2.name, team2_name, sizeof(e2.name) - 1); e2.name[sizeof(e2.name) - 1] = '\0'; } void Match::init_goal(int g1, int g2) { e1.goal = g1; e2.goal = g2; } void Match::print() { cout << e1.name << " " << e1.goal << " - " << e2.goal << " " << e2.name << endl; } int main() { Match x; x.init_name("Team1", "Team2"); x.init_goal(5, 4); x.print(); getch(); return 0; }
运行后会输出预期的Team1 5 - 4 Team2内容,无乱码。
内容的提问来源于stack exchange,提问作者Dohn Joe
相关产品推荐
相关产品推荐

