C++随机词汇抽取程序输出乱码:const char*数组传递异常排查
解决C++词库随机抽取程序的乱码问题
问题根源
你遇到的乱码“╠╠╠╠”是野指针访问导致的:
- 在
caricadirezioni和caricastrutture函数里,你把string对象的data()结果赋值给const char*数组,但局部string对象(比如direzione)在函数执行完就会销毁,对应的内存被释放,数组里的指针就变成了无效的野指针,后续访问时自然输出乱码。 - 另外代码里还有几个隐性问题:字符和字符串比较错误、随机数未初始化、数组越界,这些也会导致程序行为异常。
修复方案
1. 用vector<string>替代const char*数组
直接用C++的vector<string>来存储词库,它会自动管理内存,彻底避免野指针问题。
2. 修正字符比较错误
代码里mod == "a"这类写法错误,mod是char类型,应该和字符字面量(单引号)比较,比如mod == 'a'。
3. 初始化随机数生成器
在main函数开头添加srand(time(nullptr));,让rand()每次运行生成不同的随机序列。
4. 修复数组越界
比如autorun里rand() %5对应direzioni数组有6个元素,应该改成rand()%6;rand()%3对应struttureinterne的4个元素,改成rand()%4,避免访问超出数组范围的内存。
修改后的完整代码
#include<iostream> #include<fstream> #include<string> #include<cstdlib> #include<vector> #include<ctime> using namespace std; void scenario(const vector<string>& direzioni, const vector<string>& strutture); void print(const string& direzione, const string& struttura); int autorun(bool fronte, int aspettativa); int caricadirezioni(vector<string>& direzioni); int caricastrutture(vector<string>& strutture); void reset(vector<string>& direzioni, vector<string>& strutture); int main() { srand(time(nullptr)); // 初始化随机数生成器 int turni = 0; bool fronte = true; int aspettativa; int vaspettativa; char mod; // 改成char类型,避免字符串比较错误 vector<string> direzioni; vector<string> strutture; reset(direzioni, strutture); cout << "aspettativa turni:" << endl; cin >> aspettativa; cout << "Invio per tirare, a per generare autonomamente, c per caricare nuovi valori, x per chiudere" << endl; cin.ignore(); // 忽略之前输入的换行符 mod = getchar(); do { if (mod == 'a') { turni = autorun(fronte, aspettativa); vaspettativa = aspettativa; cout << "aspettativa di " << aspettativa << " turni raggiunta" << endl; cout << "nuova aspettativa:" << endl; cin >> aspettativa; while (aspettativa <= vaspettativa) { cout << "aspettativa non valida reinserire" << endl; cin >> aspettativa; } cout << "Invio per tirare, a per generare autonomamente, x per chiudere" << endl; cin.ignore(); mod = getchar(); } else if (mod == 'c') { caricadirezioni(direzioni); caricastrutture(strutture); } else if (mod == '\n') // 处理回车键 { if (direzioni.empty() && strutture.empty()) { cout << "errore caricare i vettori" << endl; caricadirezioni(direzioni); caricastrutture(strutture); } else { scenario(direzioni, strutture); } } if (turni == aspettativa) { vaspettativa = aspettativa; cout << "aspettativa di " << aspettativa << " turni raggiunta" << endl; cout << "nuova aspettativa:" << endl; cin >> aspettativa; while (aspettativa <= vaspettativa) { cout << "aspettativa non valida reinserire" << endl; cin >> aspettativa; } cout << "Invio per tirare, a per generare autonomamente, x per chiudere" << endl; cin.ignore(); mod = getchar(); } if (mod != 'x') mod = getchar(); } while (mod != 'x'); } void scenario(const vector<string>& direzioni, const vector<string>& strutture) { int i3 = rand() % direzioni.size(); cout << "direzione: " << direzioni[i3] << endl; int i4 = rand() % strutture.size(); cout << "struttura: " << strutture[i4] << endl; } void print(const string& direzione, const string& struttura) { ofstream out("map.txt", ofstream::app); if (out.is_open()) { out << "direzione: " << direzione << ", struttura: " << struttura << endl; } } int autorun(bool fronte, int aspettativa) { int turni = 0; const vector<string> direzionifronte = {"avanti","bivio destra","avanti","bivio destra"}; const vector<string> strutturefronte = {"deposito","nulla","nido di mitragliatrice","batteria"}; const vector<string> direzioni = {"avanti","bivio destra","bivio sinistra","incrocio","destra","sinistra"}; const vector<string> struttureinterne = {"deposito","nulla","b. ufficiali","b. dormitorio"}; while (turni <= aspettativa) { if (!fronte) { int i1 = rand() % direzioni.size(); cout << "direzione: " << direzioni[i1] << endl; int i2 = rand() % struttureinterne.size(); cout << "struttura: " << struttureinterne[i2] << endl; print(direzioni[i1], struttureinterne[i2]); } else { int i3 = rand() % direzionifronte.size(); cout << "direzione: " << direzionifronte[i3] << endl; int i4 = rand() % strutturefronte.size(); cout << "struttura: " << strutturefronte[i4] << endl; print(direzionifronte[i3], strutturefronte[i4]); if (i3 == 1) { fronte = false; } if (i3 == 3) { fronte = true; } } turni++; } cout << "mappa generata con successo" << endl; return turni; } void reset(vector<string>& direzioni, vector<string>& strutture) { direzioni.clear(); strutture.clear(); } int caricadirezioni(vector<string>& direzioni) { int n1 = 0; cout << "Numero massimo di valori (max 1000)" << endl; cin >> n1; cin.ignore(); // 忽略换行符 direzioni.reserve(n1); for (int i = 0; i < n1; i++) { string direzione; cout << "direzione " << i + 1 << ": " << endl; getline(cin, direzione); // 支持带空格的输入 direzioni.push_back(direzione); } return n1; } int caricastrutture(vector<string>& strutture) { int n2 = 0; cout << "Numero massimo di valori (max 1000)" << endl; cin >> n2; cin.ignore(); // 忽略换行符 strutture.reserve(n2); for (int i = 0; i < n2; i++) { string struttura; cout << "struttura " << i + 1 << ": " << endl; getline(cin, struttura); // 支持带空格的输入 strutture.push_back(struttura); cout << struttura << endl; } return n2; }
额外优化说明
- 改用
getline读取输入,支持带空格的词汇(比如原代码里的"nido di mitragliatrice") - 用
vector的size()替代手动维护的n1、n2,减少出错概率 - 修复了输入时的换行符残留问题,避免
getchar()读取到多余的换行
内容的提问来源于stack exchange,提问作者The Flipper Stone 782
相关产品推荐
相关产品推荐

