尝试使用重载运算符读取二进制文件时出现分段错误>>

胶水

我正在尝试读取使用以下代码创建的二进制文件:

#include <list>
#include <string>
#include <bitset>
#include <fstream>

struct Node {
  char data;
  int frequency;

  friend std::istream& operator>>(std::istream& input, Node& e) {
    input.read(&e.data, sizeof(e.data));
    input.read(reinterpret_cast<char*>(e.frequency), sizeof(e.frequency));
    return input;
  };

  friend std::ostream& operator<<(std::ostream& output, const Node& e) {
    output.write(&e.data, sizeof(e.data));
    output.write(reinterpret_cast<const char*>(&e.frequency), sizeof(e.frequency));
    return output;
  };
};

int main() {
  std::list<struct Node> list;

  for(char i='a'; i<='z'; i++) {
    struct Node n;
    n.data = i;
    n.frequency = 1;
    list.push_back(n);
  }

  std::string encoded_file = "";

  for(int i=0; i<100; i++) {
    encoded_file = encoded_file + "101010";
  }

  std::fstream output;
  output.open("output.txt", std::ios_base::out | std::ios_base::binary);

  if (output.is_open()) {
    output << list.size();
    for(int i=0; i<list.size(); i++) {
      output << list.front();
      list.pop_front();
    }

    for(long unsigned int i=0; i<encoded_file.length(); i+=8) {
      std::string data = encoded_file.substr(i, 8);
      std::bitset<8> b(data);
      unsigned long x = b.to_ulong();
      unsigned char c = static_cast<unsigned char>( x );
      output << c;
    }
  }

  output.close();

  return 0;
}

此代码似乎工作正常,并且文件output.txt生成没有问题。

但是,当我尝试使用以下代码读取文件时:

#include <list>
#include <string>
#include <bitset>
#include <fstream>
#include <iostream>

struct Node {
  char data;
  int frequency;

  friend std::istream& operator>>(std::istream& input, Node& e) {
    input.read(&e.data, sizeof(e.data));
    input.read(reinterpret_cast<char*>(e.frequency), sizeof(e.frequency));
    return input;
  };

  friend std::ostream& operator<<(std::ostream& output, const Node& e) {
    output.write(&e.data, sizeof(e.data));
    output.write(reinterpret_cast<const char*>(&e.frequency), sizeof(e.frequency));
    return output;
  };
};

int main() {
  std::list<struct Node> list;
  std::string encoded_file = "";

  std::fstream input;
  input.open("output.txt", std::ios_base::in | std::ios_base::binary);

  if (input.is_open()) {
    std::cout << "1" << std::endl;
    int size = 0;
    input >> size;
    std::cout << "size: " << size << std::endl;

    for(int i=0; i<size; i++) {
      Node node;
      input >> node;
      std::cout << node.data << " (" << node.frequency << ")" << std::endl;
      list.push_back(node);
    }
    std::cout << "2" << std::endl;

    char c;
    while(input.get(c)) {
      std::bitset<8> b(c);
      encoded_file = encoded_file + b.to_string();
    }
    std::cout << "3" << std::endl;
  }

  input.close();

  return 0;
}

我得到一个分段错误。当我尝试执行时发生错误input >> node;我检查了,显然当程序进入时Node::operator>>e.data被读取,但频率不是。

谁能给我有关如何解决此问题的任何提示?

雷米·勒博

你的Node::operator>>. 阅读时e.frequency,您缺少一个&

input.read(reinterpret_cast<char*>(&e.frequency), sizeof(e.frequency));
                                   ^

这是我之前的答案中的一个错字,您是从那里获得此代码的。我已经纠正了这个错误。


话虽如此,我在您的代码中看到了其他问题。

您正在以二进制模式创建文件,但您没有将所有内容作为二进制值流式传输到其中。只有您的Node类作为二进制流式传输,但您的其他值则作为文本流式传输。不要混合格式化方案。

output << list.size()并且output << c正在执行格式化的 I/O。用于write()二进制operator<<I/O,例如:

size_t size = list.size();
output.write(reinterpret_cast<char*>(&size), sizeof(size));
...
unsigned char c = ...;
output.write(reinterpret_cast<char*>(&c), sizeof(c));

然后在读取文件时反转该过程,例如:

input.read(reinterpret_cast<char*>(&size), sizeof(size));
...
unsigned char c;
while(input.read(reinterpret_cast<char*>(&c), sizeof(c))) {
     ...
}

此外,在您创建文件的代码中,您的第一个for循环是错误的。您正在修改listwhile 循环遍历它,从而影响其size(). 所以你最终会跳过列表中的节点。您应该使用迭代器而不是索引进行迭代,并且根本不修改列表,例如:

for(std::list<Node>::const_iterator iter = list.cbegin(); iter != list.cend(); ++iter) {
    output << *iter;
}

或更简单:

for(const auto &item : list) {
    output << item;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

读取二进制文件时出现分段错误

重载运算符<<-必须是二进制运算符

对二进制表达式无效的操作数(当同时使用两个重载运算符时)

追加和读取二进制文件时出现分段错误

C ++二进制运算符重载

尝试重载运算符时出现错误 C2296 和 C3867

添加边缘时出现R iGraph错误“二进制运算符的非数字参数”

将 std::map 写入/读取到二进制文件需要运算符

从二进制分段错误中读取时

C ++-分段错误读取二进制文件

读取二进制文件 - 分段错误

我正在尝试对运算符“+”进行二进制重载,但输出错误,我不明白为什么?

尝试在ELF二进制文件中执行注入的代码时收到分段错误

在 runc 容器中执行二进制文件时出现分段错误

R使用diff:二进制运算符错误的非数字参数

尝试重载运算符“ /”时出错

读取二进制文件时出现问题

在C ++中重载二进制关系运算符的正确方法

二进制运算符重载,隐式类型转换

C#二进制运算符重载中的泛型

尝试从当前日期计算出生日期时,二进制运算符&&的操作数类型错误

在15.10上更新rkhunter定义时出现“ [:二进制:意外运算符”消息

使用fread函数读取二进制文件时出现问题

使用重载运算符()C ++时出错

重载运算符时应该何时使用“&”?

错误重载运算符'>>'

重载运算符错误>>

Java错误:二进制运算符<的操作数类型错误

“错误:二进制运算符'&&'java的错误操作数类型