微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用“getline()”比较每一行的第三个标记?

如何解决如何使用“getline()”比较每一行的第三个标记?

输入文件:在每一行中,有一个条目是一对ID - name - GPA。值以制表符分隔。

20210001    Bill    3.61
20210002    Joe     3.21
20210003    Royce   4.32
20210004    Lucy    2.21

我必须重新排列按 GPA 排序的文件(按降序排列)。

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
    
    int main() {
       ifstream inputfile("input.txt");
       ofstream outputfile("output.txt");
    
       if (inputfile.fail()) {
          cout << "Cannot open inputfile" << endl;
       }
       if (outputfile.fail()) {
          cout << "Cannot open outputfile" << endl;
       }
    
       if (inputfile.is_open()) {
          string line;
          while (getline(inputfile,line)) {
             string token;
             stringstream ss(line);
             while (getline(ss,token,'\t')) {
             
         }
         
      }
   }
   inputfile.close();
   outputfile.close();
   return 0;
}

我不知道接下来要做什么。

解决方法

在从/到流(如文件流)进行 I/O 操作时,通常更容易创建一个类来保存文件中每条记录的数据,并为 operator>> (in) 和operator<<(出)。

示例:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

// one line in the file could possibly have this representation in your program:
struct record {
    std::uint32_t ID;
    std::string name;
    double GPA;
};

// an overload to read one line of data from an istream (like an ifstream) using getline
std::istream& operator>>(std::istream& is,record& r) {
    if(std::string line; std::getline(is,line)) {
        std::istringstream iss(line);
        if(not (iss >> r.ID >> r.name>> r.GPA)) {
            is.setstate(std::ios::failbit);
        }
    }
    return is;
}

// an overload to write one line to an ostream (like an ofstream)
std::ostream& operator<<(std::ostream& os,const record& r) {
    return os << r.ID<< '\t' << r.name << '\t' << r.GPA << '\n';
}

有了那个样板,制作实际程序就变得容易了。

int main() {
    std::ifstream inputfile("input.txt");

    // read all records from the file into a vector
    std::vector<record> records(
        std::istream_iterator<record>(inputfile),std::istream_iterator<record>{}
    );

    // sort the records according to GPA
    // if you want a decending order,just make it  return rhs.GPA < lhs.GPA;
    std::sort(records.begin(),records.end(),[](const record& lhs,const record& rhs) {
            return lhs.GPA < rhs.GPA;
        }
    );

    std::ofstream outputfile("output.txt");

    // put the result in the output file
    std::copy(records.begin(),std::ostream_iterator<record>(outputfile));
}

这个答案中可能有一些你以前没见过的东西。我将列出我认为可能需要阅读的资源:

,

如果您确切知道一行中有多少个标记:

您只需使用制表符分隔符 getline() 3 次,然后分别存储这些值。

string id;
string name;
string gpa;

getline(ss,id,'\t');
getline(ss,name,gpa,'\t');

此逻辑将存在于您的循环中,循环遍历文件中的行。

,

您可以使用 struct 来包含您的所有字段:

struct user
{
    int id; string name; double point;
};

然后将它们全部插入到 std::vector 中,最后使用 sort()comp 参数按点排序。

代码:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;

struct user
{
    int id; string name; double point;
};

vector<user> users;

void stripInfoFromString(string inp)
{
    stringstream cur(inp);
    user curUser;
    cur >> curUser.id >> curUser.name >> curUser.point;
    users.push_back(curUser);
}

bool compareUser(user x,user y)
{
    return x.point < y.point;
}

int main()
{
    string a1 = "20210001 Bill 3.61";
    string a2 = "20210002 Joe 3.21";
    string a3 = "20210003 Royce 4.32";
    string a4 = "20210004 Lucy 2.21";

    stripInfoFromString(a1);
    stripInfoFromString(a2);
    stripInfoFromString(a3);
    stripInfoFromString(a4);

    sort(users.begin(),users.end(),compareUser);
    cout << fixed << setprecision(2);
    for (user cur : users)
    {
        cout << cur.id << " " << cur.name << " " << cur.point << "\n";
    }
}

输出:

20210004 Lucy 2.21
20210002 Joe 3.21
20210001 Bill 3.61
20210003 Royce 4.32
  • 我使用标准输入/输出来最小化代码,您可以轻松切换文件输入。

更多信息:

struct : https://en.cppreference.com/w/c/language/struct

sort() : https://en.cppreference.com/w/cpp/algorithm/sort

另外,请参阅此处why is using namespace std; considered bad practice

,

我建议定义一个 struct 来保存 3 个令牌,然后为每一行创建一个 std::vector 保存该 struct 的实例。然后,您可以在第三个标记上对该 vector 进行排序。您的标头包含中已包含 <vector>

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
    
struct entry
{
    int id;
    string name;
    double gpa;
};

int main() {
    ifstream inputfile("input.txt");
    ofstream outputfile("output.txt");
    vector<entry> entries;
    
    if (inputfile.fail()) {
        cout << "Cannot open inputfile" << endl;
    }
    if (outputfile.fail()) {
        cout << "Cannot open outputfile" << endl;
    }
    
    string line;
    while (getline(inputfile,line)) {
        istringstream iss(line);
        entry e;
        string token;

        getline(iss,token,'\t');
        e.id = stoi(token);

        getline(iss,e.name,'\t');

        getline(iss,'\t');
        e.gpa = stod(token);

        /* alternatively:
        iss >> e.id >> e.name >> e.gpa;
        */

        entries.push_back(e);
    }

    inputfile.close();
    outputfile.close();

    sort(entries.begin(),entries.end(),[](const entry &e1,const entry &e2){
            return e1.gpa > e2.gpa;
        }
    );

    for (const entry &e : entries) {
        outputfile << e.id << '\t' << e.name << '\t' << e.gpa << '\n';
    }

    return 0;
}

Demo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。