cin与cin.ignore()调用异常,导致ID输出乱码问题求助
解决cin输入与类数组成员导致的乱码问题
核心问题分析
你的代码存在两个直接引发乱码的致命问题:
类成员数组声明非法
类中的char ID[][11]不符合C++语法规则——多维数组作为类成员时,必须显式指定除最后一维外的所有维度大小,否则编译器无法确定其内存布局。此时编译器会默认分配极小的空间,后续复制ID时必然发生内存越界,破坏数据结构,最终导致输出乱码。cin.ignore使用时机错误
输入n和k后,输入缓冲区残留了一个换行符。第一次循环的cin.ignore(256, '\n')能正确吃掉这个换行,但后续的cin >> id[i]会自动跳过所有空白字符(包括换行),此时再调用cin.ignore会直接吃掉下一个输入ID的首字符。比如第二个ID0000000002的第一个'0'被截断,剩下的内容无法正确读取,最终输出乱码。
修复后的代码示例(推荐用vector)
用vector<string>替代C风格数组,无需手动管理内存,安全性更高:
#include <iostream> #include <vector> #include <string> using namespace std; class watchTower { private: int numberOfAirplane; int runway; int numberOfOrders; string menu; vector<string> IDs; // 替换为动态管理的vector<string> public: void setNumberOfAirplane(int n) { numberOfAirplane = n; } void setRunWay(int k) { runway = k; } void setID(const vector<string>& ids) { IDs = ids; } void setNumberOfOrders(int q) { numberOfOrders = q; } void display(); }; void watchTower::display() { cout << numberOfAirplane << ' ' << runway << ' ' << numberOfOrders << endl; for(const auto& id : IDs) cout << id << endl; } int main() { int n, k, q; cin >> n >> k; cin.ignore(); // 仅一次忽略n和k后的换行符 vector<string> id(n); for(int i = 0; i < n; i++) { getline(cin, id[i]); // 用getline读取完整ID } watchTower input; input.setNumberOfAirplane(n); input.setRunWay(k); input.setID(id); cin >> q; input.setNumberOfOrders(q); input.display(); }
坚持使用C风格数组的修复方案
如果必须用char数组,需要通过二级指针动态分配内存:
#include <iostream> #include <cstring> using namespace std; class watchTower { private: int numberOfAirplane; int runway; int numberOfOrders; string menu; char** ID; // 二级指针实现动态数组 public: void setNumberOfAirplane(int n) { numberOfAirplane = n; // 初始化动态二维数组 ID = new char*[n]; for(int i=0; i<n; i++){ ID[i] = new char[11]; } } void setRunWay(int k) { runway = k; } void setID(char id[][11]); void setNumberOfOrders(int q) { numberOfOrders = q; } void display(); // 析构函数释放内存,避免泄漏 ~watchTower(){ for(int i=0; i<numberOfAirplane; i++){ delete[] ID[i]; } delete[] ID; } }; void watchTower::display() { cout << numberOfAirplane << ' ' << runway << ' ' << numberOfOrders << endl; for(int i = 0; i < numberOfAirplane; i++) cout << ID[i] << endl; } void watchTower::setID(char (*id)[11]) { for(int i = 0; i < numberOfAirplane; i++){ strcpy(ID[i], id[i]); // 用strcpy安全复制字符串 } } int main() { int n, k, q; cin >> n >> k; cin.ignore(); // 仅一次忽略换行 char id[n][11]; for(int i = 0; i < n; i++) { cin.getline(id[i], 11); // 用getline读取完整ID } watchTower input; input.setNumberOfAirplane(n); input.setRunWay(k); input.setID(id); cin >> q; input.setNumberOfOrders(q); input.display(); }
关键修复点总结
- 类中禁止使用未指定第一维大小的多维数组,优先用
vector<string>或动态分配的二级指针。 - 输入时,
cin >>会自动跳过空白,仅需在读取整数后调用一次cin.ignore()吃掉换行,后续用getline读取完整字符串,避免手动ignore导致的字符丢失。 - 复制C风格字符串时,用
strcpy替代逐个字符复制,确保包含字符串终止符\0。
内容的提问来源于stack exchange,提问作者Elio Baharan
相关产品推荐
相关产品推荐

