Hallo,
lang, lang ist's her, dass ich hier war ^^
Mein Problem:
Ich habe einen Vector, der auf einem Struct basiert und möchte diesem Vector nun ein Element hinzufügen.
Die Fehlermeldung:
Wo liegt da das Haar in der Suppe?Zitat
Hallo,
lang, lang ist's her, dass ich hier war ^^
Mein Problem:
Ich habe einen Vector, der auf einem Struct basiert und möchte diesem Vector nun ein Element hinzufügen.
Die Fehlermeldung:
Wo liegt da das Haar in der Suppe?Zitat
--
Geändert von Niji-chan (20.07.2009 um 10:21 Uhr)
Die Compilerausgabe ...\main.cpp|32|error: incompatible types in assignment of `char*' to `char[10]'| bezieht sich auf folgende Quelltextzeile: vWeightList[0].chDate = chDate;
Hier willst du einem Array vom Typ char was zuweisen. Da chDate prinzipiell die Adresse von chDate[0] darstellt und diese durch die Kompilierung schon fest steht, kannst du sie konventionell nicht ändern.
Ein Lösungsansatz wäre die Daten einzeln zu verschieben oder einen Datentyp zu deklarieren, der die Adresse mit beinhaltet.
@Niji:
Du verstehst nicht wie man mit C-Feldern umgeht. Du versuchst ein Feld in ein anderes zu kopieren, indem du die Adresse, unter der das erste Feld erreichbar ist, zu der Adresse, unter der das zweite Feld erreichbar ist, änderst.
So interpretiert es nämlich der Compiler, obwohl deine tatsächliche Intention die ist, die Werte der Elemente des ersten Feldes gleich denen des zweiten zu setzen.
Der folgende Code zeigt wie man auf verschiedene Weisen eine tatsächliche Kopie eines Feldes erzielt:
Übrigens (mir ist nicht klar, ob es dir bewusst ist): Es ist egal, ob du den Parametertyp als 'char*', 'char[]', oder 'char[10]' deklarierst. In allen Fällen handelt es sich um einen Zeiger auf einen 'char' und die optionale Deklaration der Länge dient höchstens dem Leser als Dokumentation: "Ah, hier erwartet er ein Feld aus 'char's mit der Länge 10".
Zum weiteren Code will ich mich erstmal nur soweit äußern, dass er auf den ersten Blick wenig Sinn macht, angesichts dessen, was du mit dem Stack anstellst und deiner Menülogik. Ich denke, da gibt es noch weitere, nicht weniger gravierende Verständnisprobleme und vermute, dass du nach der Lösung des aktuellen Problems, noch mit weiteren konfrontiert sein wirst.
Vielen lieben Dank!
Da hab ich wohl noch einiges zu lernen
Auf jeden Fall funktioniert es jetzt und ich kann jetzt weiter C++ üben
Danke auch für die schnellen Antworten
lg
--
Ich würde noch den memcpy-Aufruf folgendermaßen schreiben...
...denn memcpy erfordert, dass beide Blöcke mindestens die übergebene Länge haben.
Wenn man davon ausgeht, dass es nullterminierte C-Strings sind (was die Parameter date und chDate sein können und im Grunde sind), wäre strlen angebrachter.
Eigentlich gibt es aber überhaupt keinen Grund, wieso du hier nicht Strings anstelle von C-Strings verwenden solltest.
Geändert von Kyuu (12.07.2009 um 22:48 Uhr)
Ok - thx nochmal
Habe jetzt ein neues Problem …
Ich speicher die eingegebenen Daten in einer binary-Datei. Wenn ich diese jedoch bei einem Neustart auslese kommt da nur irgend ein Blödsinn heraus - es steht dann also nicht sowas wie
sondern in etwa
Hat vll. jemand eine Idee woher das kommt / soll ich nochmal den Code posten, wie er zur Zeit aussieht?
lg
--
Ich weiss nicht genau, was du meinst. Eine Binaerdatei enthaellt doch nicht zwangsweise Text etc. Kommt drauf an, was du speicherst. Und eine Datei veraendert sich doch auch nicht beim Reboot. Sieht mir ehr nach einem Pointerfehler aus.
Ohne Code kommen wir hier definitiv nicht weiter. Ich bin jetzt aber erst einmal 2 Wochen in "Urlaub".
Problem tritt also an sich bei CDragonfly() am Anfang beim Auslesen der Datei auf.
Edit: ach ja - und schönen Urlaub![]()
--
Sorry, aber diesen Wust werde ich mir nicht antun, zumal der aktuell Code Tag grausam ist. Im dunklen Design ist er faktisch unlesbar. Und da er nur 80 Zeichen breit ist, dein Code aber meher hundert Zeichen breit, allerdings der Scrollbalken nur ganz unten ist, ist das mehr als unleserlich. Und man kann nichtmal mit STRG+A den Quellcode markieren, um ihn in einem anderen Editor zu kopieren. Du solltest dir einen kuerzeren Codestil zulegen. EOE80 oder EOE120 maximal. Aber ich weiss selbst, wie schwer das ist.
Edit: Ok, ich hab mir doch mal die Muehe gemacht, den Code in einen Editor zu kopieren und nen fluechtigen Blick drauf zu werfen.
Das ist riesiger Bloedsinn. ostream.write kannst du im Grunde nur auf SDTs (Simple Data Types) anwenden, also auf byte, int, float, char und ihre arrays.
Mit komplizierten Datentypen wie Structs, Classes oder Pointern funktioniert das nicht, wenn du auch bei einem struct ohne Methoden zufaellig Glueck haben kannst.
Der Grund ist der, dass bei komplexen Datenstrukturen zusaetzliche Informationen gespeichert werden, die du so nicht zu Gesicht bekommst, wie Alignments im Speicher fuer schnelleren Datenzugriff, Loop-Up-Tabellen virtueller Methoden, Referenzen auf Elternklassen, Methodenpointer, usw. Wenn du nun so ein Objekt direkt in eine Datei schreibst, wird auch das genau gemacht: eine Kopie des aktuellen Objektes. Wenn du es aber wieder einladen willst, kommt nur noch schrott raus. Ueberall dort, wo du eine Array oder einen Pointer im Datentyp hast (und in Classes hast du viele Pointer, auch wenn du sie nicht immer siehst), wird ja nicht der Inhalt des Pointers gespeichert, sondern nur die Addresse, worauf er zeigt. Beim Einlesen liest er auch nur diese Addresse und dagt dem Objekt "Dort stehen deine Daten". Da diese Daten aber niemals gespeichert wurde, zeigt nun der Pointer irgendwo ins Nirvana, und dort kann alles moegliche stehen, und das ist fuer dein Programm einfach nur Datenmuell. Daher bekommst du nach jedem Neustart auch andere Werte, da der Pointer nach dem Einladen immer an die selbe Stelle zeigt, aber immer was anderes drin steht.
Wie loest man nun das Problem ? Dazu wuerde ich dir empfehlen, dass du statt ostream.write einfach den << und den >> operator verwendest. Du solltest fuer ALLE(!) deine Klassen, die du speichern willst, den istream& operator>>(istream& instream) fuer die Eingabe und den ostream& operator<< (ostream& outstream) fuer die Ausgabe ueberladen. Diese Operatoren geben dann z.B. ueber outstream << fWeight; die Daten der einzelnen SDTs in den Stream aus bzw lesen sie in der selben Reihenfolge ein. Wenn du einen Member hast, der dynamisch alloziiert wird (z.B. ein Array mittels new) dann erzeugst du das entsprechende Array und liest alle Werte einzeln ein. Wenn deine Klasse Member hat, die ihrerseits Objekte sind, rufst du den entsprechenden operator>> oder operator<< der dazugehoehrigen Klasse auf, so dass sich die Klasse selber darum kuemmert. Wenn du allerdings nicht von dir geschriebene Objekte hast, die die >> und << nicht implementieren, musst du selbst Hand anlegen, z.B. bei std::vector<typ>. Im operator<< machst du dann sowas wie
und im operator>> machst du dann den umgekehrten Code
Wenn du das alles sauber und stimmig implementiert hast, so dass deine I/O nur noch auf SDTs basiert, klappt das auch mit dem Einlesen und Auslesen.