C++药店药品管理程序文件读写脏数据问题求助
药品管理程序脏数据问题排查与修复
核心问题与修复方案
1. 二进制读写含std::string的结构体导致脏数据
std::string内部存储的是指向堆内存的指针,直接用fread/fwrite二进制读写时,写入的是指针地址而非实际字符串内容。读取时指针指向的内存已经失效,会产生乱码或内存错误。
修复方式:改用文本格式读写,逐字段处理字符串:
// 替换原caricahdd函数 void caricahdd(s_farmaci farmaco[]) { n = 0; ifstream in("dati.txt"); if (!in.is_open()) { cout << "errore apertura file" << endl; return; } while (in >> farmaco[n].codice) { in.ignore(); // 跳过换行符 getline(in, farmaco[n].descrizione); in >> farmaco[n].prezzo >> farmaco[n].disponibilita; n++; if (n >= Num) break; // 防止数组越界 } in.close(); cout << "dati caricati correttamente" << endl; } // 替换原salvahdd函数 void salvahdd(s_farmaci farmaco[]) { ofstream out("dati.txt"); if (!out.is_open()) { cout << "errore apertura file" << endl; return; } for (int i = 0; i < n; i++) { // 注意是 <n,不是 <=n out << farmaco[i].codice << endl; out << farmaco[i].descrizione << endl; out << farmaco[i].prezzo << endl; out << farmaco[i].disponibilita << endl; } out.close(); cout << "dati salvati correttamente" << endl; }
2. 冒泡排序函数中的致命赋值错误
在bubblesort函数中,交换库存数量时写错了变量,把药品编号赋值给了库存:
// 原错误代码 tempquantita = vet[i].disponibilita; vet[i].disponibilita = vet[i + 1].disponibilita; vet[i + 1].disponibilita = tempcodice; // 这里应该是tempquantita
修复后:
tempquantita = vet[i].disponibilita; vet[i].disponibilita = vet[i + 1].disponibilita; vet[i + 1].disponibilita = tempquantita;
这个错误会直接破坏库存数据,是脏数据的重要来源。
3. 文件读取时feof使用错误
原caricahdd函数用while (!feof(file))判断循环,会导致多读一次无效数据,因为feof在读取失败后才会置位。修复后改用文本读写已经避免了这个问题,若坚持二进制读写,应改为:
while (fread(&farmaco[n], sizeof(s_farmaci), 1, file) == 1) { n++; if (n >= Num) break; }
4. 保存函数的循环边界错误
原salvahdd函数循环条件是i <= n,会多写入一个未初始化的元素(索引n),导致文件末尾出现脏数据。修正为i < n即可。
5. 库存不足排序的冗余循环
sottoscorta函数中外层的for (int x = 0; x < tanti; x++)完全多余,冒泡排序只需要执行一次,重复循环会浪费性能,直接删除即可:
void sottoscorta(s_farmaci vet[], int tanti) { // 去掉外层冗余循环 int i, j; //sorting farmacs description for (j = 0; j < tanti - 1; j++) for (i = 0; i < tanti - 1 - j; i++) // 优化:减少不必要的比较 if (vet[i].descrizione > vet[i+1].descrizione) scambia(vet, i, i+1); for (int k = 0; k < tanti; k++) { if (vet[k].disponibilita < 3) { cout << endl; cout << " il codice del farmaco e':" << vet[k].codice << endl; cout << " la descrizione del farmaco e':" << vet[k].descrizione << endl; cout << " il prezzo del farmaco e':" << vet[k].prezzo << endl; cout << " la disponibilita' del farmaco e':" << vet[k].disponibilita << endl; } } }
总结
脏数据主要来自三个方面:std::string的二进制读写错误、冒泡排序的变量赋值错误、文件读写的边界错误。按照上述方案修复后,程序的脏数据问题应该能彻底解决。
内容的提问来源于stack exchange,提问作者Alexandro Tornese
相关产品推荐
相关产品推荐

