写入/读取标准::设置< T >到/从二进制文件读取
Write/read std::set< T > to/from binary file
我正在尝试编写一对写入/读取函数,用于分别将std::set< T >
数据容器存储/检索到二进制文件中/从二进制文件中检索。我的writeSet()
函数似乎可以按预期工作,并存储std::set< T >
数据容器,没有任何明显的问题。但是,readSet()
函数没有,并抛出"未处理的异常 [...]访问冲突读取位置 0xFEEEFEF6"异常 main()
函数返回 EXIT_SUCCESS
。
据我而言(使用 Visual Studio 2013(,readSet()
实际上似乎确实成功读取了二进制文件,并将数据正确分配给寻址std::set< T >
数据容器。当VS2013崩溃时,它为我提供了中断程序执行的机会,并将我指向xtree.h头文件中的错误。具体而言,调试器抱怨_Pnext
以下部分的行|| _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
:
#if _ITERATOR_DEBUG_LEVEL == 2
void _Orphan_ptr(_Myt& _Cont, _Nodeptr _Ptr) const
{ // orphan iterators with specified node pointers
_Lockit _Lock(_LOCK_DEBUG);
const_iterator **_Pnext = (const_iterator **)_Cont._Getpfirst();
if (_Pnext != 0)
while (*_Pnext != 0)
if ((*_Pnext)->_Ptr == this->_Myhead
|| _Ptr != 0 && (*_Pnext)->_Ptr != _Ptr)
_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
else
{ // orphan the iterator
(*_Pnext)->_Clrcont();
*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
}
我的最小工作解决方案如下:
writeSet()
: 将 std::set
template < class T >
void writeSet(const std::string& filePath, const std::string fileName, std::set<T>& data)
{
// Construct binary file location string using filePath and fileName inputs
std::stringstream file; file << filePath.c_str() << "/" << fileName.c_str();
std::ofstream fileStream; fileStream.open(file.str().c_str(), std::ios::out | std::ios::binary);
// First write number of std::set elements held by data, and then write std::set block to binary file
std::set<T>::size_type n = data.size();
fileStream.write(reinterpret_cast<char*>(&n), sizeof(std::set<T>::size_type));
fileStream.write(reinterpret_cast<char*>(&data), sizeof(T)*n);
fileStream.close();
}
readSet()
: 从二进制文件中读取 std::set
template < class T >
void readSet(const std::string& filePath, const std::string fileName, std::set<T>& data)
{
// Construct binary file location string using filePath and fileName inputs
std::stringstream file; file << filePath.c_str() << "/" << fileName.c_str();
std::ifstream fileStream; fileStream.open(file.str().c_str(), std::ios::in | std::ios::binary);
// First read number of elements stored in binary file, then write file content to adresses std::set data variable
std::set<T>::size_type n;
fileStream.read(reinterpret_cast<char*>(&n), sizeof(std::set<T>::size_type));
fileStream.read(reinterpret_cast<char*>(&data), sizeof(T)*n);
fileStream.close();
}
main()
:重现"未处理异常"错误的最小主函数
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
int main()
{
// Define binary file read/write directory
const std::string path("C:/data");
// writeSet() testing...
std::set<int> writeSetData;
writeSetData.insert(1); writeSetData.insert(3);
writeSetData.insert(0); writeSetData.insert(2);
writeSet(path, "binaryFile", writeSetData);
// readSet() testing...
std::set<int> readSetData;
readSet(path, "binaryFile", readSetData);
std::cout << "readSetData= {";
for (std::set<int>::iterator it = readSetData.begin(); it != readSetData.end(); ++it){
std::cout << *it << ", ";
} std::cout << "}" << std::endl;
return EXIT_SUCCESS;
}
你所有的T
都是 POD 吗?否则,制作二进制副本几乎毫无意义,而不是创建语义副本。
此外,集合管理的数据保存在由set
管理的动态分配内存中,而不是set
本身。
第三点,当你试图在那里写入任意数量的元素时,这个空间不会神奇地增长或缩小。
您必须通过手动插入元素来要求集合增长!
作为旁注,std::string
非常适合字符串连接,无需中断std::stringstream
!
相关文章:
- 正在读取二进制文件(is_open)
- 读取二进制文件并解释为整数
- 读取二进制文件直到结束 c++
- 如何在标准c ++中流式传输/读取二进制文件的中间部分并写入另一个文件?
- 读取二进制文件的惯用C++17标准方法是什么
- 从末尾读取二进制文件
- C++逐个字符读取二进制文件字符
- 读取二进制文件大小的短自上周以来停止工作
- 读取二进制文件时出现问题
- 读取二进制文件时如何输出?
- C++:如何在线程中读取二进制文件并将其写入另一个线程?
- 在C 中读取二进制文件会返回意外值
- 尝试读取二进制文件会清除文件本身
- C 读取二进制文件
- 通过C 读取二进制文件的问题
- ifstream读取二进制文件在发行模式下工作,但在调试模式下不使用
- 分段 追加和读取二进制文件时出错
- 使用C++中的MsgPack读取二进制文件
- 有没有一种优雅的方法来读取二进制文件并将其内容复制到向量<int>
- 如何读取二进制文件并在屏幕上打印 3?