如何将文件数值存入已初始化的列数不固定的动态分配矩阵
解决动态分配矩阵读取文件数值的问题
嘿,我明白你的问题了——你已经搞定了动态矩阵的空间分配,能根据文件每行的列数给每行分配内存,但不知道怎么把文件里的数值填进去对吧?咱们一步一步来解决这个问题。
首先,你的原代码有个小问题:第一次读取文件时,你用getline扫完了整个文件来统计列数、分配空间,但此时文件指针已经跑到末尾了,再想读取数值就没内容了。另外,你随机生成的noCartiere是2到14之间的数,得确保只读取文件的前noCartiere行,不然可能会出现行数不匹配的情况。
我给你调整并完善了代码,不仅能完成数值读取,还处理了一些边界情况,比如文件行数不足的问题,同时添加了内存释放的逻辑(动态分配的内存一定要记得释放,不然会内存泄漏):
#include <iostream> #include <fstream> #include <sstream> #include <vector> #include <cstdlib> #include <ctime> #include <string> using namespace std; void alocaSiCitesteTablou(int& noCartiere, int**& noLocuitori, int*& noStraziArray) { srand(time(NULL)); noCartiere = rand() % 13 + 2; cout << "noCartiere generat random este: " << noCartiere << endl; ifstream f("Text.txt"); if (!f.is_open()) { cerr << "Eroare: Nu s-a putut deschide fisierul Text.txt!" << endl; return; } vector<string> linii; string linie; int numarLiniiCitite = 0; // Citim primele 'noCartiere' linii din fisier while (getline(f, linie) && numarLiniiCitite < noCartiere) { linii.push_back(linie); numarLiniiCitite++; } f.close(); // Daca fisierul are mai putine linii decat noCartiere, ajustam noCartiere if (numarLiniiCitite < noCartiere) { cout << "Atentie: Fisierul are doar " << numarLiniiCitite << " linii. Se ajusteaza noCartiere la aceasta valoare." << endl; noCartiere = numarLiniiCitite; } // Alocam spatiu pentru matrice si pentru array-ul de numar de strazi per cartier noLocuitori = new int* [noCartiere]; noStraziArray = new int[noCartiere]; for (int i = 0; i < noCartiere; i++) { istringstream iss(linii[i]); string cuvant; int numarElemente = 0; // Numaram cate elemente sunt in linia curenta while (iss >> cuvant) { numarElemente++; } noStraziArray[i] = numarElemente; // Alocam spatiu pentru linia curenta din matrice noLocuitori[i] = new int[numarElemente]; // Citim valorile si le salvam in matrice istringstream iss2(linii[i]); int j = 0; while (iss2 >> noLocuitori[i][j]) { j++; } } } void elibereazaMemorie(int**& noLocuitori, int*& noStraziArray, int noCartiere) { if (noLocuitori != nullptr) { for (int i = 0; i < noCartiere; i++) { delete[] noLocuitori[i]; } delete[] noLocuitori; noLocuitori = nullptr; } if (noStraziArray != nullptr) { delete[] noStraziArray; noStraziArray = nullptr; } } int main() { int noCartiere; int** noLocuitori = nullptr; int* noStraziArray = nullptr; alocaSiCitesteTablou(noCartiere, noLocuitori, noStraziArray); if (noLocuitori == nullptr || noStraziArray == nullptr) { return 1; } // Afisam matricea pentru verificare cout << "\nMatricea de locuitori per strazi:\n"; for (int i = 0; i < noCartiere; i++) { cout << "Cartierul " << i+1 << ": "; for (int j = 0; j < noStraziArray[i]; j++) { cout << noLocuitori[i][j] << " "; } cout << endl; } // Eliberam memoria alocata dinamic elibereazaMemorie(noLocuitori, noStraziArray, noCartiere); return 0; }
关键说明:
- 保存文件行到vector:我把读取到的文件行先存在
vector<string>里,这样就不用重复打开文件,直接从内存里读取数值,避免了文件指针到末尾的问题。 - 记录每行列数:新增了
noStraziArray数组,用来存储每行的元素个数,这样后续使用矩阵的时候,你能知道每行有多少个数值,不会越界。 - 边界处理:如果文件里的行数比随机生成的
noCartiere少,代码会自动调整noCartiere的数值,防止出现错误。 - 内存释放:专门写了
elibereazaMemorie函数,用完矩阵后一定要调用它,释放动态分配的内存,避免内存泄漏。
你只需要确保你的Text.txt文件放在程序能找到的路径下,运行代码就能看到读取后的矩阵啦。
内容的提问来源于stack exchange,提问作者Dragos Efrim
相关产品推荐
相关产品推荐

