<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Binary Files C vs CPP]]></title><description><![CDATA[<p>ich hab vor, eine Struct in einer Datei zu speichern. Und zwar handelt es sich um eine Binaerdatei. Fuer C funkst das wunderbar. Bisher habe ich in 90% meiner Programme nur mit den C-File-Funktionen gearbeitet. Sind halt doch irgendwie<br />
einfach in der Handhabe. Nun möcht ich die Struct auch mit den fstream-Klassen in eine Datei bringen. Allerdings erlauben die read und write-Methoden nur char's. Habe bereits mit memcpy herumexperimentiert, aber ohne Erfolg.</p>
<p>Hat wer einen Tipp fuer mich. Da wo &quot;MIST&quot; steht, hängt es.</p>
<p>WICHTIG:<br />
Ich möchte nicht jeden Teil der Struct extra anfassen, Konvertieren und dann beim Auslesen wieder mühevoll zurückkonvertieren. Da bleib ich lieber bei meinem ersten Beispiel</p>
<pre><code class="language-cpp">struct THighscore
{
	std::string name;
	unsigned int points;
};

int main(int argc, char *argv[])
{
	THighscore *pHighscore1 = new THighscore;
	THighscore *pHighscore2 = new THighscore;

	pHighscore1-&gt;name = &quot;Franz&quot;;
	pHighscore1-&gt;points = 125;

	// BEGIN C
	FILE *pFile;

	// Write
	pFile = fopen(&quot;highscore_c.txt&quot;, &quot;wb&quot;);
	fwrite(pHighscore1, sizeof(THighscore), 1, pFile);
	fclose(pFile);

	// Read
	pFile = fopen(&quot;highscore_c.txt&quot;, &quot;rb&quot;);
	fread(pHighscore2, sizeof(THighscore), 1, pFile);
	fclose(pFile);
	// END C

	// BEGIN CPP
	fstream finout;

	// Write
	finout.open(&quot;highscore_cpp.txt&quot;, ios::in|ios::binary);
	finout.write( /* MIST */ );
	finout.close();

	//Read
	finout.open(&quot;highscore_cpp.txt&quot;, ios::out|ios::binary);
	finout.read( /* MIST */ );
	finout.close();
	// END CPP

	// Output
	cout &lt;&lt; pHighscore2-&gt;name &lt;&lt; endl;
	cout &lt;&lt; pHighscore2-&gt;points &lt;&lt; endl;

	delete pHighscore1;
	delete pHighscore2;

	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/261637/binary-files-c-vs-cpp</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 04:31:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/261637.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 21 Feb 2010 20:08:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Binary Files C vs CPP on Sun, 21 Feb 2010 20:08:38 GMT]]></title><description><![CDATA[<p>ich hab vor, eine Struct in einer Datei zu speichern. Und zwar handelt es sich um eine Binaerdatei. Fuer C funkst das wunderbar. Bisher habe ich in 90% meiner Programme nur mit den C-File-Funktionen gearbeitet. Sind halt doch irgendwie<br />
einfach in der Handhabe. Nun möcht ich die Struct auch mit den fstream-Klassen in eine Datei bringen. Allerdings erlauben die read und write-Methoden nur char's. Habe bereits mit memcpy herumexperimentiert, aber ohne Erfolg.</p>
<p>Hat wer einen Tipp fuer mich. Da wo &quot;MIST&quot; steht, hängt es.</p>
<p>WICHTIG:<br />
Ich möchte nicht jeden Teil der Struct extra anfassen, Konvertieren und dann beim Auslesen wieder mühevoll zurückkonvertieren. Da bleib ich lieber bei meinem ersten Beispiel</p>
<pre><code class="language-cpp">struct THighscore
{
	std::string name;
	unsigned int points;
};

int main(int argc, char *argv[])
{
	THighscore *pHighscore1 = new THighscore;
	THighscore *pHighscore2 = new THighscore;

	pHighscore1-&gt;name = &quot;Franz&quot;;
	pHighscore1-&gt;points = 125;

	// BEGIN C
	FILE *pFile;

	// Write
	pFile = fopen(&quot;highscore_c.txt&quot;, &quot;wb&quot;);
	fwrite(pHighscore1, sizeof(THighscore), 1, pFile);
	fclose(pFile);

	// Read
	pFile = fopen(&quot;highscore_c.txt&quot;, &quot;rb&quot;);
	fread(pHighscore2, sizeof(THighscore), 1, pFile);
	fclose(pFile);
	// END C

	// BEGIN CPP
	fstream finout;

	// Write
	finout.open(&quot;highscore_cpp.txt&quot;, ios::in|ios::binary);
	finout.write( /* MIST */ );
	finout.close();

	//Read
	finout.open(&quot;highscore_cpp.txt&quot;, ios::out|ios::binary);
	finout.read( /* MIST */ );
	finout.close();
	// END CPP

	// Output
	cout &lt;&lt; pHighscore2-&gt;name &lt;&lt; endl;
	cout &lt;&lt; pHighscore2-&gt;points &lt;&lt; endl;

	delete pHighscore1;
	delete pHighscore2;

	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1859262</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859262</guid><dc:creator><![CDATA[BasicMan01]]></dc:creator><pubDate>Sun, 21 Feb 2010 20:08:38 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Files C vs CPP on Sun, 21 Feb 2010 20:31:14 GMT]]></title><description><![CDATA[<p>BasicMan01 schrieb:</p>
<blockquote>
<p>Fuer C funkst das wunderbar.</p>
</blockquote>
<p>Das glaube ich dir jetzt mal so gar nicht. Denn das was du da machst funktioniert überhaupt nicht, wenn in dem struct ein std::string ist. Mach aus dem C-Teil mal zwei Programme eins zum Lesen und eins zum Schreiben und lass dich überraschen, was da für ein Mist rauskommen wird. Bei &quot;Franz&quot; als Name funktioniert es mit viel Glück noch, aber nimm mal einen Namen mit mehr als 16 Zeichen.</p>
<p>Die wirklich saubere Art und Weise die immer funktioniert (sogar plattformübergreifend, selbst wenn man Dateien aus unterschiedlichen Plattformen austauscht) ist das Konvertieren des structs, in Fachkreisen auch <em>Serialisierung</em> genannt. Das ist gar nicht mal so schwer, deswegen weiß ich nicht, warum du dich so dagegen sträubst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859271</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 21 Feb 2010 20:31:14 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Files C vs CPP on Sun, 21 Feb 2010 20:46:08 GMT]]></title><description><![CDATA[<p>OK 1:0 fuer dich. Ich hab mich eh schon gewundert, warum bei sizeof([struct]) immer 20 rauskam. Wäre ja auch zu schön. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> ...<br />
Dann werd ich deinen Tipp der Serialisierung mal beherzigen und mir da was basteln. Dann lern ich auch mal wieder was.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859280</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859280</guid><dc:creator><![CDATA[BasicMan01]]></dc:creator><pubDate>Sun, 21 Feb 2010 20:46:08 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Files C vs CPP on Mon, 22 Feb 2010 17:59:08 GMT]]></title><description><![CDATA[<p>Ich habe mir zwei Funktionen gebastelt, die so diversen Speicher in einen C-String kopiert und wieder zurueck. Den resultierende C-String speichere ich in eine Datei, lese ihn wieder aus und kopiere alles wieder raus in die richtigen Variablen. Mal so platt formuliert.</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void foo(char *target, T const &amp;s, size_t pos=0)
{
	memcpy(target+pos, &amp;s, sizeof(s));
}

template&lt;typename T&gt;
void bar(T &amp;s, const char *source, size_t pos=0)
{
	memcpy(&amp;s, source+pos, sizeof(s));
}
</code></pre>
<p>Was die Funktionen tun, muss ich ja net weiter erläutern.<br />
1. Kann ich solche Geschichten spaeter fuer meine Serialisierung verwenden?</p>
<p>2. Was mich noch interessiert: Warum funktioniert das bei einem std::string nicht, wenn ich ein Leseprogramm und ein Schreibprogramm trenne. Aber es funktioniert, wenn ich in ein und dem selben Programm die Schreib -und Leseoperationen ausfuehre. Laut meinem Verständnis sind es blos Pointer auf einen Adressbereich, die dann beim Auslesen auf was anderes zeigen. Liege ich damit richtig?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859691</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859691</guid><dc:creator><![CDATA[BasicMan01]]></dc:creator><pubDate>Mon, 22 Feb 2010 17:59:08 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Files C vs CPP on Mon, 22 Feb 2010 18:45:08 GMT]]></title><description><![CDATA[<p>Die Verwendung von memcpy geht völlig am eigentlichen Problem vorbei. Du hast dir da bloß einen eigenen Ersatz für reinterpret_cast gebastelt, das hättest du auch gleich haben können. Das Problem ist folgendes:</p>
<p>Wie funktioniert so ein string? Nun, das ist eigentlich nicht weiter festgelegt, aber im groben machen die meisten Implementierungen das so:</p>
<pre><code class="language-cpp">class std::string
{
  char *data;
  unsigned int size;
  // Und möglicherweise noch ein paar mehr Member
}
</code></pre>
<p><code>data</code> ist ein Zeiger auf die eigentlichen Daten. Diese Daten liegen irgendwo auf dem Heap. Wenn du deinen String mit memcpy/reinterpret_cast in eine Datei schreibst, dann schreibst du in die Datei bloß die Größe und den Wert des Zeigers (das heißt die Adresse der Daten). Die eigentlichen Daten werden nicht gespeichert, die liegen ja ganz woanders, nämlich da wo <code>data</code> hinzeigt. Wenn du den String wieder lädst, dann hat der aus der Datei geladene String nur die Größe und eine Speicheradresse. An der Speicheradresse liegen, nachdem du das Programm neu gestartet hast, irgendwelche Sachen, aber bestimmt nicht die eigentlichen Daten. Woher sollten sie auch kommen? Und daher geht das schief.</p>
<p>Wenn du im gleichen Programm speicherst und lädst, hast du eine leicht andere Situation. Es wird zwar wieder nur der Zeiger mit der alten Adresse wieder hergestellt, aber an dieser Adresse liegen noch die alten Daten, da sich zwischendurch nichts verändert hat. Daher funktioniert das. Aber auch nicht richtig, denn eigentlich gehört der Speicher dem aus der Datei geladenen String nicht (das heißt er hat den Speicher nicht selbst mit new/malloc reserviert), was zu allerlei Problemen führen kann.</p>
<p>Und std::string ist noch eine relativ einfache Datenstruktur. Eine std::list beispielsweise hat eine viel kompliziertere Zeigerstruktur. Vergiss das Vorgehen mittels memcpy lieber, das funktioniert nunmal einfach nur bei ganz ganz einfachen Datenstrukturen und selbst da ist es nicht portabel.</p>
<p>Hier noch ein paar Antworten auf ungestellte Fragen:<br />
<a href="http://www.parashift.com/c++-faq-lite/serialization.html" rel="nofollow">http://www.parashift.com/c++-faq-lite/serialization.html</a><br />
<a href="http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html" rel="nofollow">http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859712</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859712</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 22 Feb 2010 18:45:08 GMT</pubDate></item><item><title><![CDATA[Reply to Binary Files C vs CPP on Mon, 22 Feb 2010 18:56:37 GMT]]></title><description><![CDATA[<p>Danke fuer die ausfuehliche Erklaerung <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /> ... damit bestaetigt sich meine<br />
Vermutung zwecks Pointer. Fuer die memcpy-Geschichte hatte ich auch garnicht vor,<br />
ganze Objekte zu uebergeben. Meine entfernte Idee bestand eher darin, die Sachen in simble Datentypen umzuwandeln. Denn Serialisierung, so hab ich es verstanden, sorgt dafuer, ein komplexes Objekt mit all seinen Verknuepfungen und Referenzen in einen Datenstrom umzuwandeln, den man dann gut speichern kann.</p>
<p>Im Moment moechte ich bewusst keine fertige Library verwenden wie boost. Ich denke, dass es spaeter Sinn macht, wenn ich wirklich massig Objekte serialisieren muss. Im Moment will ich fuer das Verstaendnis und zum Lernen eher nur was kleines uebersichtliches selber basteln. :p</p>
<p>Aber ich les mich erstmal in deine Links ein ... die machen nen guten Eindruck <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859721</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859721</guid><dc:creator><![CDATA[BasicMan01]]></dc:creator><pubDate>Mon, 22 Feb 2010 18:56:37 GMT</pubDate></item></channel></rss>