Problem mit struct array
-
Hey,
vielleicht könnt ihr mir kurz helfen, komm nicht mehr weiter//Variablen definition int anzahlHamster; typedef struct HamsterStruct { int x; int y; int richtung; } Hamster; Hamster hamster[]; void init(){ printf("Geben Sie die Anzahl der Hamster ein: "); scanf_s("%d", &anzahlHamster); for (int g = 0; g < anzahlHamster; g++){ printf("Bitte geben Sie die Werte f\x81r den Hamster %d ein:\n", g + 1); printf("X-Koordinate: "); scanf_s("%d", hamster[g].x); printf("Y-Koordinate: "); scanf_s("%d", hamster[g].y); printf("Richtung: "); scanf_s("%d", hamster[g].richtung); } zeichnen(); }
//Unwichtige Sachen rausgekürzt
Also mein Problem besteht darin das ich ein Hamster struct erstellen will was die Koordinaten übergeben bekommt für den jeweiligen hamster (Hamster anzahl wird vom user bestimmt, genauso wie die koordinaten x,y,richtung)
Nun erstens weiß ich nicht wie ich das Array immer so hinbekomme das es genau "hamsterAnzahl" stellen hat.
Zweitens bekomm ich bei diesem Porgramm, diese Fehler angezeigt:Fehler 1 error LNK2001: Nicht aufgelöstes externes Symbol ""struct HamsterStruct * hamster" (?hamster@@3PAUHamsterStruct@@A)". C:\..\Quelle.obj Fehler 2 error LNK1120: 1 nicht aufgelöste Externe C:\..\Aufgabe9.exe Aufgabe9
Danke für die Hilfe
-
Das Problem ist nicht das struct, sondern das Array an sich. Damit gehst du sehr falsch um. Lassen wir das struct mal weg:
int hamster[];
Sieht das für dich immer noch sinnvoll aus?
Allgemein:
Globale Variablen: Pfui! Ironischerweise würdest du hier eine aussagekräfigere Meldung bekommen, hättest du wenigstens das Array lokal gemacht:int foo[]; // Gültiges C, aber bedeutet was anderes, als du denkst int main() { int bar[]; // Schlicht und einfach falsch. }
-
Ok da fehlt die "länge" des Arrays also z.B.
int hamster[5]
Allerdings will ich ja das Array so "lang" haben wie der User es eingibt also theoretisch
int hamster[hamsterAnzahl]
So funktioniert es dann aber auch nicht weil "anzahlHamster" keine konstante ist.
-
Wenn du die Feldgröße dynamisch haben möchtest, brauchst du entweder C99 (oder neuer) und dessen variable length arrays (VLA) oder du musst die manuelle Speicherverwaltung bemühen (malloc & Co.). Da du anscheinend mit Visual Studio arbeitest, steht dir C99 nicht zur Verfügung. Und wenn du solche Fragen stellst, dann - nichts für ungut - wirst du wohl auch Probleme mit manueller Speicherverwaltung haben. Zumindest, wenn ich dir die Konzepte im Rahmen eines Forenbeitrags erkläre, da das Thema dafür zu komplex ist. Wie lernst du C? Manuelle Speicherverwaltung kommt vermutlich bald nach den Arrays und structs dran.
-
Ok jetzt hab ich mal ein wenig zu malloc etc gesucht und auch gefunden (Verstehen tu ichs jedeoch noch nicht so recht
)
Ich hab mir mein Code jetzt so zusammengebastelthamster = (Hamster*) malloc(anzahlHamster*sizeof(Hamster)); if (hamster == NULL) { printf("\nKein Speicher vorhanden.\n"); }
Visual studio zeigt mir zumindest keine Fehler an, allerdings stürzt mein programm nach der eingabe von "anzahlHamster" immer ab
-
Max89 schrieb:
Ok jetzt hab ich mal ein wenig zu malloc etc gesucht und auch gefunden (Verstehen tu ichs jedeoch noch nicht so recht
)
Ja, das war zu erwarten. Du brauchst ein Lehrbuch, keine kurzen Codefetzen aus dem Internet. Dynamische Speicherverwaltung ist recht frickelig und man muss genau verstehen, was man tut.
Ich hab mir mein Code jetzt so zusammengebastelt
hamster = (Hamster*) malloc(anzahlHamster*sizeof(Hamster)); if (hamster == NULL) { printf("\nKein Speicher vorhanden.\n"); }
Visual studio zeigt mir zumindest keine Fehler an, allerdings stürzt mein programm nach der eingabe von "anzahlHamster" immer ab
Das kann 1000 Ursachen haben. Vollständiges Minimalbeispiel bitte.
Als ersten Verdacht mach mal aushamster = (Hamster*) malloc(anzahlHamster*sizeof(Hamster));
ein
hamster = malloc(anzahlHamster*sizeof(Hamster));
Das ist hier schließlich C, nicht C++ (und in C++ würde man überhaupt gar nicht erst malloc benutzen). Deine IDE unterschlängelt dir das eventuell als Fehler (weil VS eine C++-IDE ist und sich meines Wissens nach nicht auf C umstellen lässt), aber es sollte trotzdem übersetzt werden (der Compiler kann nämlich schon C, bloß die Syntaxhervorhebung nicht). Falls es beim Übersetzen einen Fehler/Warnung gibt in der Art von "da wird ein Zeiger aus einem int gemacht, ohne Cast", hast du die Ursache gefunden:
#include <stdlib.h>
vergessen.
-
Ok dann nochmal alles was dazu gehört:
int anzahlHamster; typedef struct HamsterStruct { int x; int y; int richtung; } Hamster; Hamster *hamster; void init(){ printf("Geben Sie die Anzahl der Hamster ein: "); scanf_s("%d", &anzahlHamster); hamster = malloc(anzahlHamster*sizeof(Hamster)); //Hamster * hamster = (Hamster*) malloc(anzahlHamster*sizeof(Hamster)); if (hamster == NULL) { printf("\nKein Speicher vorhanden.\n"); } for (int g = 0; g < anzahlHamster; g++){ printf("Bitte geben Sie die Werte f\x81r den Hamster %d ein:\n", g + 1); printf("X-Koordinate: "); scanf_s("%d", hamster[g].x); printf("Y-Koordinate: "); scanf_s("%d", hamster[g].y); printf("Richtung: "); scanf_s("%d", hamster[g].richtung); } zeichnen(); }
Mit deinem vorschlag gibt er mir nun folgende Fehlermeldung aus:
Fehler 1 error C2440: '=': 'void *' kann nicht in 'Hamster *' konvertiert werden c:\..\hamster.h 68 1 Aufgabe9
-
Also erstmal der Fehler:
scanf_s("%d", hamster[g].x); // Und die Zeilen, die genau so aussehen
Da ist hamster[g].x ein int. Aber scanf will einen Zeiger auf diesen int! Also:
scanf_s("%d", &hamster[g].x);
Zu deiner Fehlermeldung: Das war zu erwarten, du verwendest anscheinend den C++-Compiler vom Visual Studio. Du bekommst Fehler, da C und C++ eben doch nicht (mehr) so kompatibel sind, wie das gern behauptet wird. Andere Fehler, wie die Variablendeklaration innerhalb der for-Anweisung, was in C(89) nicht erlaubt ist, werden im Gegenzug nicht erkannt (in C++ ist das nämlich erlaubt). Daher: Nutz einen C-Compiler. In den Projekteigenschaften deines Projekts sollte es eine Einstellung geben in der Art von "als C++ compilieren", die setzt du auf "als C compilieren". Alternativ (vielleicht ist es auch noch zusätzlich nötig, ich habe VS nicht) kannst und solltest du auch der Quellcodedatei die Endung .c statt .cpp geben.
Siehe zum Beispiel auch:
http://www.daniweb.com/software-development/cpp/threads/16256/compiling-c-in-visual-studio.net
oder
http://www.swarthmore.edu/NatSci/tali/E15/Visual_C.html
oder
Google: visual studio compile cDie Stelle mit dem malloc sollte dann ohne Schwierigkeiten übersetzt werden, dafür jedoch sollte es an dem for in Zeile 27 scheitern. Damit du nicht total frustriert bist, hier ein streng standardkonformes* und korrektes Programm:
#include <stdio.h> #include <stdlib.h> typedef struct { int x; int y; int direction; } Hamster; int main(void) { unsigned int num_hamsters, i; Hamster *hamsters; printf("Geben Sie die Anzahl der Hamster ein: "); scanf("%u", &num_hamsters); hamsters = malloc(num_hamsters*sizeof(*hamsters)); if (hamsters == NULL) { printf("\nKein Speicher vorhanden.\n"); return EXIT_FAILURE; } for (i = 0; i < num_hamsters; ++i) { printf("Bitte geben Sie die Werte für den Hamster %u ein:\n", i + 1); printf("X-Koordinate: "); scanf("%d", &hamsters[i].x); printf("Y-Koordinate: "); scanf("%d", &hamsters[i].y); printf("Richtung: "); scanf("%d", &hamsters[i].direction); } /* Zur Kontrolle */ puts("Liste aller Hamster:"); for (i = 0; i < num_hamsters; ++i) { printf("Hamster %u: x = %d\ty = %d\tRichtung = %d\n", i + 1, hamsters[i].x, hamsters[i].y, hamsters[i].direction); } /* Wichtig: */ free(hamsters); return EXIT_SUCCESS; }
Man sollte eigentlich noch prüfen, ob die Nutzereingaben überhaupt gültig waren und Sinn machen (Eine Nutzereingabe, die zig Gigabyte Speicher reservieren könnte, ungeprüft zu übernehmen, ist keine gute Idee), aber das spare ich mir mal für diese kleine Demo. Beachte auch subtile Unterschiede zwischen meinem Code und deinem, wie zum Beispiel die Form des typedef und viele andere mehr. Das sind keine wichtigen Sachen, bloß kleinere Stilfragen.
*: Nein, es ist nicht ganz 100% standardkonform. Ich konnte den Umlaut nicht 100% klugscheißersicher darstellen, daher habe ich die wohl einfachste und portabelste Methode gewählt und ihn einfach hin geschrieben :p . In C99 und C++ könnte man (sofern man nicht diese einfache Methode vorzieht), wenn man ganz penibel ist,
\u00fc
fürü
schreiben.
-
Und beachte die Zeile 24 bei dem Code von SeppJ.
Du hast zwar den Fehler gemeldet, aber dann munter weiter gemacht.