c++ - 来自输入文件的数组

标签 c++ arrays parsing

我是 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/

相关文章:

javascript - Angular ui-select array of objects - 第一项不可选择

javascript - 在 Node.js 中将 log4j 错误流解析为 JSON

java - 使用 DateTimeFormatter ofPattern 解析日期

c++ - 基本的 linux C++ 网络 : connection refused, 但是没有出现错误

c++ - 如何在类之间共享昂贵的计算?

c++ - 将库链接到 visual studio 2015 中的 android ndk 应用程序

C++:简单递归搜索函数的运行时错误

c++ - 在 C++ 中加密/解密 ROT

php - 如何在数组树中查找值?

c - 如何将指针设置为二进制文件中的字符串?