输入文件中的数组
Arrays from input file
我是一个非常初学c++的人,现在我需要处理来自输入文件的数据,该文件有以下几行:
2012019109 Proadan legea Coaa女65
这些是学生编号,姓名(2或3个字),性别和考试成绩。
我必须为每个属性创建一个数组。此外,我不知道输入文件可能包含多少行(最多100,000行),但输入文件中的第一个数字将是该文件中的行数。
一旦我设置了一个数组,我需要实现一个函数来按Name的字母字符串顺序(升序)对记录进行排序,然后将这些记录放入输出文件中。
我试过以以下方式做第一部分(设置数组),但似乎是错误的:
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;
}`
一旦我有了这些数组,我只需要找到一种按字母顺序排序的方法,但即使有了这些第一步,我还是卡住了。正如您可能会说的,我不太了解编程,并将感谢任何帮助!
编辑:谢谢你的意见和帮助,我真的很感谢你的时间。我的问题是,因为这是在学校的一个项目工作,我被要求使用数组(由于一些无法解释的原因)。
仅供参考,在输入文件中,号码/姓名/性别/分数用TAB ('/t')分隔。
是否有任何方法来解决上述问题,同时坚持数组和不使用向量或地图?
问题是你试图在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实际上太大了,无法容纳一个有符号的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);
}
要对得到的向量进行排序,可以使用STL中的排序算法,它使用类的"<"操作符,因此您只需重载该操作符并对向量使用sort。
sort(database.begin(), database.end());
使用这样定义的比较运算符:
bool operator< (const Person & p1, const Person& p2)
{
//just an example
return p1.UID.compare(p2.UID) < 0;
}
你可以在这里了解更多重载操作符。
编辑
如果你不能使用vector,这并不会真正改变循环代码(只需将newPerson替换为相应的已经分配的Person对象(类似于database[x])。
对于排序,你仍然可以使用STL的排序算法,它应该在迭代器上工作,但它可以在指针上工作。这不是一个简洁的解决方案,也可能不是你应该做的。
否则你可以实现你自己的排序算法,这真的是一个教科书案例。
请注意,如果你不使用结构体,并且一直使用多个数组,那么你就不能使用STL排序算法,并且排序算法中的数据交换将比必要的要复杂得多。
首先,使用:
for (int y=0 ; y<x, y++)
而不是while
但你可以使用矢量或地图让你的生活变得更容易。我知道,给你完整的代码不是个好主意。最好自己试一下。但是我想让你们有动力去学习STL。这真的很简单。(你可以找到更有效的方法)
int x;
fin >> x; //this is the first number within ...
std::multimap<std::string,std::string> rows;
std::string row;
while(getline(fin, row))
{
std::stringstream r(row) ;
std::string name;
getline(row, name, 't'); // ID
getline(row, name, 't'); // name
rows.insert(std::make_pair(name,row));
}
fout << x << std::endl;
for (const auto& r : rows)
fout << r << std::endl;
if (x!=rows.size())
//.... error?
没有地图吗?…
struct row{string ID, name, rest;};
…
fout << x << std::endl;
row *rows=new row[x];
for(int i=0;i<x;++i)
{
getline(fin, rows[i].ID, 't'); // ID
getline(fin, rows[i].name, 't'); // name
getline(fin, rows[i].rest );
}
std::sort(rows,rows+x,[](const row& r1, const row& r2)
{return r1.name<r2.name;} );
for( i=0;i<x;++i)
fout<<rows[i].ID<<'t'<< rows[i].name<<'t'<< rows[i].rest<<endl;
没有lambda ?这里有一个完整的例子
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
struct row{string ID, name, rest;};
bool operator < (const row& r1, const row& r2)
{ return r1.name<r2.name;}
ostream &operator<<(ostream&o, const row&r)
{ return o<<r.ID<<'t'<< r.name<<'t'<< r.rest<<endl; }
int main()
{ int x=2;
row rows[]={{"1","BB","r1"},{"2","AA","r2"}};//=new row[x];
std::sort(rows,rows+x);
for(int i=0;i<x;++i)
cout<<rows[i];
}
或者这里:(我希望你不要简单地复制代码,而是去阅读参考资料,享受学习使用标准c++库的乐趣)
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
using namespace std;
struct row{string ID, name, rest;};
bool operator < (const row& r1, const row& r2)
{ return r1.name<r2.name;}
ostream &operator<<(ostream&o, const row&r)
{ return o<<r.ID<<'t'<< r.name<<'t'<< r.rest <<endl; }
int main()
{
stringstream fin,fout;
fin<< "5" << endl;
fin<< "2012019874tZooadan Legeaf CoaatFemalet65"<<endl;
fin<< "1111090909tZuilia PereztFemalet701" <<endl;
fin<< "2012019109tProadan Legeaf CoaatFemalet65"<<endl;
fin<< "2345019176tTrroadan LegeaftFemalet98" <<endl;
fin<< "2012019109tAAroadan Legeaf CoaatFemalet65"<<endl;
int x;
fin >> x; //this is the first number within ...
row *rows=new row[x];
for(int i=0;i<x;++i)
{
getline(fin, rows[i].ID, 't'); // ID
getline(fin, rows[i].name, 't'); // name
getline(fin, rows[i].rest );
}
std::sort(rows,rows+x);
fout << x << std::endl;
for(int i=0;i<x;++i)
fout<<rows[i];
delete []rows;
cout<<"Input:n"<< fin.str()<<"nOutput:n"<< fout.str();
}
- 如何将内容数组写入文本文件?
- C++将文本文件中的数据读取到结构数组中
- 将值从二维数组输出到文本文件
- C++数据文件、数组和计算赋值
- 如何拆分文件中.txt字母并使用c ++使用数组进行扑克?
- 如何在 C++ 中从文件中读取字符数组(带有一些空格)
- 如何从txt文件中读取多个不同长度的数组?
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- 如何在 C++ 中将文件中的逗号分隔数字读取到数组中?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- C++编程从外部文本文件定义数组大小
- 使用矢量将文本文件中的输入存储到 2D 数组中
- 如何将文本文件的特定行读取到 int 类型的数组中C++?
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 将系数存储在头文件的数组中("does not name a type"错误)
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 从文件读取,并写入函数C++中的数组
- 如何从具有两列的.txt文件创建并行数组?
- 读取二维数组文件