如何从txt文件中读取多个不同长度的数组?

How to read in multiple arrays with varying lengths from txt file?

本文关键字:数组 txt 文件 读取      更新时间:2023-10-16

我对C++很陌生,并尝试从具有以下数据的文本文件中读取某些数组:

Number_of_students 3
Number_of_assignments 3
Paul Smith 5 6 7
Tina Smith 6 7 7
Andrew Smith 4 5 10

我需要做的是将名称放入一个数组中,将它们后面的数字放入一个单独的数组中。下面是我的代码,每当我尝试从其中一个数组输出值时,我都会得到 0。

#include <string>
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
const int MAX_CLASS_SIZE = 100;
const int MAX_NUMBER_OF_ASSIGNMENTS = 100;
string names[MAX_CLASS_SIZE][2]
int scores[MAX_CLASS_SIZE][MAX_NUMBER_OF_ASSIGNMENTS]
int number_of_students
int number_of_assignments
ifstream file;
file.open("grades.txt");
if (file.is_open())
{
string nos;
string noa;
file >> nos >> number_of_students;
file >> noa >> number_of_assignments;
for (int i = 0; i < number_of_students; i++) {
for (int j = 0; j < 2; j++) {
for (int s = 0; s < number_of_assignments; s++) {
file >> names[i][j] >> scores[i][s];
}
}
}
file.close();
}
else cout << "Unable to open file";
return 0;
}

您正在阅读每个学生的 6 个名字和 6 个分数。

for (int j = 0; j < 2; j++) {
for (int s = 0; s < number_of_assignments; s++) {
file >> names[i][j] >> scores[i][s];
}
}

我想你的意思是:

for (int j = 0; j < 2; j++) {
file >> names[i][j];
}
for (int s = 0; s < number_of_assignments; s++) {
file >> scores[i][s];
}

如果这可以修复它。是时候审查最佳实践了:代码审查

#include <cstddef>  // std::size_t
#include <cstdlib>  // EXIT_FAILURE
#include <string>
#include <fstream>
#include <iostream>
int main()
{
// All caps for MAX_CLASS_SIZE and MAX_NUMBER_OF_ASSIGNMENTS suggests
// that you #defined them. Better use constant expressions than preprocessor
// defines since they are typesafe:
constexpr std::size_t MAX_CLASS_SIZE{ 42 };            // I don't know what would        
constexpr std::size_t MAX_NUMBER_OF_ASSIGNMENTS{ 42 }; // be good numbers.
std::string names[MAX_CLASS_SIZE];
int scores[MAX_CLASS_SIZE][MAX_NUMBER_OF_ASSIGNMENTS];
std::size_t number_of_students;     // std::size_t because it is guaranteed that
std::size_t number_of_assignments;  // it is big enough to hold all possible sizes
// of objects in memory and indexes into arrays.
char const *filename{ "scores.txt" };  // give it a name so you can use it in
// error messages
std::ifstream file{ filename };        // use the constructor of ifstream to
// open the file
if (!file.is_open()) {  // if the file couldn't be opened exit early instead
// of encasing everything in one giant if-block
std::cerr << "Couldn't open "" << filename << "" for reading :(nn";
return EXIT_FAILURE;
}
std::string dummy;  // i named it dummy cause thats just what it is
// always check if read operations didn't fail:
if (!(file >> dummy >> number_of_students >> dummy >> number_of_assignments)) {
std::cerr << "Couldn't read number of students and/or number of assignments from ""
<< filename << "" :(nn";
return EXIT_FAILURE;
}
if (number_of_students > MAX_CLASS_SIZE ||
number_of_assignments > MAX_NUMBER_OF_ASSIGNMENTS)
{
std::cerr << "I am sorry, but I was not designed to handle more than " 
<< MAX_CLASS_SIZE << " Students or more than "
<< MAX_NUMBER_OF_ASSIGNMENTS << " assignments :(nn";
return EXIT_FAILURE;
}
std::size_t num_students_read{}; // keep track of how many students we read
//   / only continue if reading
//  /  didn't fail
for (std::size_t i{}; i < number_of_students && (file >> names[i]); ++i) {
// As long as the next thing we read is not the first score it is
// part of the name:
std::string name_part;
while (!(file >> scores[i][0]) && (file.clear(), (file >> name_part))) {
names[i] += ' ';
names[i] += name_part;
}
// We read the name and the first score.
// Now read the following number_of_assignments - 1 scores:
std::size_t num_scores_read{ 1 };    // keep track of how many scores we actually read
for (std::size_t s{1}; s < number_of_assignments && (file >> scores[i][s]); ++s)
++num_scores_read;
if (num_scores_read != number_of_assignments) {  // and check if the number
// of scores read matches
// the number that was
// promised
std::cerr << "There are scores missing for " << names[i] << " :(nn";
return EXIT_FAILURE;
}
++num_students_read;
}
if (num_students_read != number_of_students) {
std::cerr << "There sould be " << number_of_students << " students but I was "
<< "only able to read " << num_students_read << " :(nn";
return EXIT_FAILURE;
}
// print what we read:
for (std::size_t i{}; i < number_of_students; ++i) {
std::cout << names[i] << ": ";
for (std::size_t s{}; s < number_of_assignments; ++s)
std::cout << scores[i][s] << ' ';
std::cout.put('n');
}
// no need for file.close() ... the destructor of ifstream will
// take care of that.
}