Frage

Ich habe eine Datenstruktur definiert als

struct myDataStruct
{
   int32_t header;
   int16_t data[8];
}

und ich mag einen Zeichenstrom nehmen und es in einen myData Strom verwandeln. Was Stream-Klasse soll ich verlängern? Ich möchte eine benutzerdefinierte Stream-Klasse erstellen, so dass ich die Dinge tun kann wie

myDataStruct myData;
myDataStruct myDataArray[10];

myDataStream(ifstream("mydatafile.dat"));
myDataStream.get(myData);
myDataStream.read(myDataArray, 10);
War es hilfreich?

Lösung

Statt myDataStream.get(myData), was Sie tun, ist Überlastung operator>> für Ihren Datentyp:

std::istream& operator>>(std::istream& is, myDataStruct& obj)
{
  // read from is into obj
  return is;
}

Wenn Sie in ein Array lesen möchten, schreiben Sie einfach eine Schleife:

for( std::size_t idx=0; idx<10; ++idx ) 
{
   myDataStruct tmp;
   if( is >> tmp )
     myDataArray[idx] = tmp;
   else
     throw "input stream broken!";
}

eine Funktionsvorlage verwenden, sollten Sie auch in der Lage den Operator für Arrays auf der rechten Seite zu überlasten (aber das habe ich noch nie versucht):

template< std::size_t N >
std::istream& operator>>(std::istream& is, myDataStruct (&myDataArray)[N])
{
  // use loop as above, using N instead of the 10
}

Aber ich kann nicht entscheiden, ob dieses wunderschöne oder verabscheuungswürdig ist.

Andere Tipps

Wenn Sie mit unformatierter Eingabe arbeiten, sollen Sie wahrscheinlich direkt in binärer Form lesen. Normalerweise würden Sie einige Compiler spezielle Richtlinie verwenden, um Datenstrukturen ohne Polsterung zu erstellen und dann nur lesen / schreiben aus einer Datei.

// 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
}

Die Compiler-Direktive zu deaktivieren Polsterung für VS anders sein könnte (ich glaube, die Pragma-Direktive funktioniert sowohl in gcc und VS, aber ich habe immer das Attribut verwendet wird).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top