我是 C++ 的初学者,现在我需要处理来自输入文件的数据,该文件包含大量如下行:
2012019109 Proadan Legeaf Coaa Female 65
这些是学号、姓名(2 或 3 个单词)、性别和考试成绩。
我必须为每个属性创建一个数组。另外,我不知道输入文件可能包含多少行(最多 100,000),但输入文件中的第一个数字将是该文件中的行数。
一旦我设置了一个数组,我需要实现一个函数来按名称的字母字符串顺序(升序)对记录进行排序,然后将它们放入输出文件中。
我试过按照以下方式对第一部分(设置数组)进行操作,但它似乎是错误的:
ifstream fin;
ofstream fout;
fin.open("input.txt");
fout.open("output.txt");
if (fin.fail()) {
cout << "Fail to open inout.txt" << endl;
exit(1);
}
int x;
fin >> x; //this is the first number within the input text file, indicating the number of lines in the file. I would use this to determine the size of the arrays:
int UID [x];
string name [x];
string gender [x];
int score [x];
int y = 0;
// In the following part, I am trying to extract the information into the different arrays, one by one, increasing the number of the element from 0 up till x. Complier error says no matching function for call for the UID and score lines.
while (y!=x, y++) {
getline(fin, UID [y], '\t');
getline(fin, name [y], '\t');
getline(fin, gender [y], '\t');
getline(fin, score [y], '\t');
break;
}`
一旦我有了这些数组,我只需要找到一种方法来按字母顺序排列它,但即使完成了这些第一步,我还是卡住了。您可能会说,我对编程知之甚少,非常感谢任何帮助!
编辑: 感谢您到目前为止的评论和帮助,非常感谢您抽出时间。我的问题是,由于这是学校的项目工作,我需要使用数组(出于某些无法解释的原因)。
仅供引用,在输入文件中,号码/姓名/性别/分数由制表符 ('/t') 分隔。
有什么方法可以在坚持使用数组而不使用 vector 或映射的同时解决上述问题?
最佳答案
问题是您正在尝试读取 int 中的字符串:
getline(fin, UID [y], '\t');
UID[y]是一个int,而getline只能存入一个字符串。
所以你必须首先将它存储在一个缓冲区字符串中,然后使用 atoi 将它转换为一个 int例如:
string UID_buffer;
getline(fin, UID_buffer, '\t');
UID[y] = atoi(UID_buffer.c_str());
但是还有另一个问题,你的UID实际上太大了,无法放入一个signed int中,你可以尝试将它们存储在unsigned 32或64位中,但只存储可能更简单它们作为字符串。
OOP方法会建议您使用一个类来存储每个对象,而不是使用多个数组:
struct Person {
string UID;
string name;
string gender;
int score;
};
然后只创建一个数组:
Person* database = new Person[x];
您还可以创建一个 C++ 可调整大小的容器,例如 vector , 排序会容易得多:
vector<Person> database;
另请注意,您应该使用for 循环而不是while。
对于循环代码,你可以先用getline读取一行,做一个stringstream从中取出并在此流上使用 getline 来读取该行的每个元素,如下所示:
for(int y = 0, y < x; y++) {
getline(fin, line);
stringstream linestream(line);
Person newPerson;
getline(linestream, newPerson.UID, '\t');
getline(linestream, newPerson.name, '\t');
getline(linestream, newPerson.gender, '\t');
string buffer;
getline(linestream, buffer, '\t');
newPerson.score = atoi(buffer.c_str());
database.push_back(newPerson);
}
要对您将获得的 vector 进行排序,您可以使用 sort来自 STL 的算法,它使用类的“<”运算符,因此您只需重载此运算符并对 vector 使用排序。
sort(database.begin(), database.end());
使用您定义的比较运算符:
bool operator< (const Person & p1, const Person& p2)
{
//just an example
return p1.UID.compare(p2.UID) < 0;
}
您可以了解有关重载运算符的更多信息 here .
编辑
如果您不能使用 vector,那并不会真正改变循环代码(只需将 newPerson 替换为相应的已分配的 Person 对象(类似于 database[x])。
现在对于排序,您仍然可以使用 STL 的排序算法,它应该适用于迭代器,但它也适用于指针。这不是一个完美的解决方案,而且可能不是您应该做的。
否则你可以实现自己的排序算法,它真的是一个textbook case .
请注意,如果您不使用结构并继续使用多个数组,那么您将无法使用 STL 排序算法,并且排序算法中的数据交换会比必要的复杂得多。
关于c++ - 来自输入文件的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15967790/