【问题标题】:How to sort a struct from binary file with sort c++如何使用sort c ++从二进制文件中对结构进行排序
【发布时间】:2021-12-16 08:52:04
【问题描述】:

编译器报错:Expression: invalid operator

#include<iostream>
#include<fstream>
#include<algorithm> 

using namespace std;

struct ticket{
    char destination[50];
    char  flightNumber[50];
    char Aircraft[50];
};

bool comparator(ticket a, ticket b)
{
    return a.destination < b.destination;
    
}

int main()
{
    const int SIZE = 6;
    char mydestination[40]; 
    ticket newA[SIZE];
    fstream f;
    f.open("records.dat", ios::in | ios::binary);
    
    if (f.is_open())
    {
        
        f.read(reinterpret_cast<char*>(newA), SIZE *sizeof(ticket));
        f.close();
    }
    else
        cout << "ERROR\n";
    
    sort(newA, newA + SIZE, comparator);
    
    for (ticket& s : newA)
    {
        cout << s.destination;
        cout << s.Aircraft;
        cout << s.flightNumber << endl;     
    }
    system("pause");
    return 0;
}

【问题讨论】:

  • a.destination &lt; b.destination 不比较字符串;它比较地址(表现出未定义的行为,因为它们不是指向同一数组的指针)。要比较 C 风格的字符串,请使用 strcmp
  • 您应该将comparator 的参数作为const 引用传递,因为您没有修改它们。该引用可防止编译器复制您的变量(按值传递)。
  • "Expression: invalid operator
  • 优先使用 std::string 文本而不是字符数组。您可以使用== 比较std::string,但对于字符数组,您需要strcmp
  • 这并没有解决问题,而是养成使用有意义的值初始化对象的习惯,而不是默认初始化它们并立即覆盖默认值。在这种情况下,这意味着将fstream f; f.open("records.dat", ios::in | ios::binary); 更改为fstream f("records.dat", ios::in | ios::binary);。此外,由于f 仅用于输入,其类型应为ifstream 而不是fstream。这样你就不必告诉构造函数它是一个输入流:ifstream f("records.dat", ios::binary); 就足够了。

标签: c++ file struct


【解决方案1】:

如 cmets 中所述,使用 &lt; 只会比较地址。

要实际比较字符串,您可以使用std::lexicographical_compare。将比较器更改为

bool comparator(const ticket& a, const ticket& b) {
    return std::lexicographical_compare(std::begin(a.destination), std::end(a.destination), std::begin(b.destination), std::end(b.destination));
}

【讨论】:

    【解决方案2】:

    您的“字符串”不是 c++,它们是 c 风格的字符数组。因此,按照 cmets 中的建议,您的最佳选择是使用:

    int strcmp (const char* str1, const char* str2);
    
    bool comparator(ticket a, ticket b)
    
    {
    return strcmp(&a.destination,&b.destination);
    }
    

    或者只是删除比较器功能并使用:

        sort(newA, newA + SIZE, strcmp(&a.destination,&b.destination));
    

    你可能需要

    #include

    但我最好用 c++ 风格重写我的代码

    【讨论】:

    • 将要序列化的数据以“较低级别的格式”表示的情况并不少见,例如使用char 数组而不是std::string。这并不意味着我们只能使用 C 函数,但您的解决方案确实是另一个不错的选择。此外,如果您需要在 C++ 代码中包含“C 字符串函数”的标头,最好使用#include &lt;cstring&gt; 而不是#include &lt;string.h&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多