You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cin与cin.ignore()调用异常,导致ID输出乱码问题求助

解决cin输入与类数组成员导致的乱码问题

核心问题分析

你的代码存在两个直接引发乱码的致命问题:

  1. 类成员数组声明非法
    类中的char ID[][11]不符合C++语法规则——多维数组作为类成员时,必须显式指定除最后一维外的所有维度大小,否则编译器无法确定其内存布局。此时编译器会默认分配极小的空间,后续复制ID时必然发生内存越界,破坏数据结构,最终导致输出乱码。

  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:25:23