カスタムデータのiostream
-
20-09-2019 - |
質問
私は
として定義されたデータ構造を持っていますstruct myDataStruct
{
int32_t header;
int16_t data[8];
}
と私は文字ストリームを取得し、MYDATAストリームにそれを有効にします。私は何ストリームクラスを拡張する必要がありますか?私は私のようなものを行うことができるようにカスタムストリームクラスを作成したいと思います。
myDataStruct myData;
myDataStruct myDataArray[10];
myDataStream(ifstream("mydatafile.dat"));
myDataStream.get(myData);
myDataStream.read(myDataArray, 10);
解決
代わりに
myDataStream.get(myData)
の、何をやっていることは、あなたのデータ型の過負荷operator>>
あります:
std::istream& operator>>(std::istream& is, myDataStruct& obj)
{
// read from is into obj
return is;
}
あなたは配列に読み込みたい場合は、単にループを書きます:
for( std::size_t idx=0; idx<10; ++idx )
{
myDataStruct tmp;
if( is >> tmp )
myDataArray[idx] = tmp;
else
throw "input stream broken!";
}
関数テンプレートを使用して、または(これは私が試したことがない)右辺の配列のための演算子をオーバーロードすることができます。
template< std::size_t N >
std::istream& operator>>(std::istream& is, myDataStruct (&myDataArray)[N])
{
// use loop as above, using N instead of the 10
}
しかし、私は、これは豪華か卑劣であるかどうかを決定することはできません。
他のヒント
あなたがフォーマットされていない入力を使用している場合は、
は、おそらくバイナリ形式で直接読み取る必要があります。通常はなしパディングとデータ構造を作成するために、いくつかのコンパイラ固有のディレクティブを使用することになり、その後、単にファイルからの読み出し/書き込みます。
// Gcc
#pragma pack(1) // option 1: pragmas
struct frame {
std::uint32_t header;
std::uint16_t data[8];
} __attribute((packed)); // option 2: packed attribute
#pragma pack(0)
bool operator==( data const & lhs, data const & rhs )
{
bool result = lhs.header == rhs.header;
for ( int i = 0; i < 8; ++i )
{
result &= lhs.data[i] == rhs.data[i];
}
return result;
}
int main()
{
frame data = { 10, 1, 2, 3, 4, 5, 6, 7, 8 };
std::ofstream out( "data.bin", ofstream::binary );
out.write( reinterpret_cast<char*>(&data), sizeof(data) );
out.close();
std::ifstream in( "data.bin", ifstream::binary );
frame readed;
in.read( reinterpret_cast<char*>(&readed), sizeof(readed) );
in.close();
std::cout << (readed == data) << std::endl; // 1
}
VSのためのパディングを無効にするコンパイラ・ディレクティブは、(私はプラグマディレクティブはGCCにし、VSの両方の作品と考えているが、私はいつもの属性を使用している)異なる場合があります。
所属していません StackOverflow