如何将存储自定义M_SP_NA_1结构体的std::vector内容写入txt文件
问题原因分析
第一种方案报错原因
std::ostream_iterator<uint8_t>要求迭代的元素类型为uint8_t,但你传入的是M_SP_NA_1结构体类型,既没有默认类型转换规则,也没有重载对应的operator<<,因此触发报错。
第二种方案输出不符合预期原因
std::ostream::write的第二个参数是要写入的字节总数,你传入的spSignals.size()是元素数量(此处值为1),仅写入了1个字节,内容自然不符合预期。
额外提示:如果结构体存在字节对齐填充,直接内存写入还会把填充的无效字节写入文件,最好先声明结构体为1字节对齐。
解决方案
场景1:写入原始二进制内容到文件
首先给结构体添加1字节对齐声明,避免填充无效字节:
#pragma pack(push, 1) // 强制1字节对齐 struct M_SP_NA_1 { uint8_t firstbyte = 0x01; uint8_t signalType; uint8_t cot; uint8_t asduLSB = 0x00; uint8_t asduMSB; uint8_t iot1 = 0x00; uint8_t iot2; uint8_t iot3 = 0x00; uint8_t valflag1 = 0x00; uint8_t valflag2; }; #pragma pack(pop) // 恢复默认对齐
修改写入代码:
std::ofstream outfile("C:\\Users\\*****\\Desktop\\signals.txt", std::ios::out | std::ios::binary); // 写入总字节数 = 元素个数 * 单个结构体大小 outfile.write(reinterpret_cast<const char*>(spSignals.data()), spSignals.size() * sizeof(M_SP_NA_1)); outfile.close();
该方案写入的是原始二进制字节,用十六进制编辑器打开即可看到预期的01 01 09 00 07 00 0b 00 00 d1序列。
场景2:写入十六进制格式的可读文本到文件
如果需要txt文件为可直接查看的十六进制字符串,遍历每个结构体的成员转成十六进制输出即可:
#include <iomanip> // 引入格式化工具 std::ofstream outfile("C:\\Users\\*****\\Desktop\\signals.txt"); // 全局设置十六进制输出,不足2位补前导0 outfile << std::hex << std::setfill('0'); for (const auto& obj : spSignals) { // 按顺序输出每个成员的十六进制值,空格分隔 // 转uint16_t是为了避免uint8_t被识别为char输出字符而非数值 outfile << std::setw(2) << static_cast<uint16_t>(obj.firstbyte) << " " << std::setw(2) << static_cast<uint16_t>(obj.signalType) << " " << std::setw(2) << static_cast<uint16_t>(obj.cot) << " " << std::setw(2) << static_cast<uint16_t>(obj.asduLSB) << " " << std::setw(2) << static_cast<uint16_t>(obj.asduMSB) << " " << std::setw(2) << static_cast<uint16_t>(obj.iot1) << " " << std::setw(2) << static_cast<uint16_t>(obj.iot2) << " " << std::setw(2) << static_cast<uint16_t>(obj.iot3) << " " << std::setw(2) << static_cast<uint16_t>(obj.valflag1) << " " << std::setw(2) << static_cast<uint16_t>(obj.valflag2) << "\n"; } outfile.close();
输出的文件内容就是可读的01 01 09 00 07 00 0b 00 00 d1。
内容的提问来源于stack exchange,提问作者east1000
相关产品推荐
相关产品推荐

