URL: https://www.overclockers.at/coding-stuff/pointer_problem_in_c_74427/page_1 - zur Vollversion wechseln!
Hi, ich habe folgendes Problem:
Ich habe ein binäres Baum Programm, es sollen Char mit einer Länge von 20 Zeichen eingelesen werden und in gewissen "Orders" wieder ausgegben werden.
Nur bei mir scheint es so, als hätte ich was mit dne Pointer falsch gemacht, nur ich komme ienfach nicht darauf
Weiß wer wo bzw. was nicht korrekt ist?
Ich schätze, dass der Wert vom Pointer help der Funktion inorder nicht korrekt übregeben wird.
Danke,
Brunnman
EDIT #1:
Ich glaube jetzt einen Fehler entdeckt zu haben, komme aber nicht weiter. Fehler:
Root wird irgendwie verändert (wodurch auch immer ) und dadurch wird nicht das letzte Element ausgegeben.
Nur wo verändere ich den root?!?
EDIT #2:
in void eingabe(...) bekomme ich immer nur in den 1. If-Zweig, so als wäre help immer neu.
Help hat am Ende der Funktion einen wert der übergeben wird, aber am beginn der rekursion müsst help dann ja den korrekten wert haben, hat jedoch immer den wert NULL...
Code:#ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <strings.h> #include <stdlib.h> typedef struct node { char info[21]; struct node *left, *right; } NODE; typedef NODE *Ref; Ref root = NULL; void eingabe(char datensatz[21], Ref root); void ausgabe(Ref help); void print(Ref help); void inorder(Ref help); void fehler(); int main(int argc, char *argv[]) { Ref help=NULL; int ein=1; char datensatz[21]; while(ein!=0) { printf("%s","\nBitte waehlen Sie die gewuenschte Funktion aus dem Menue:\n\n"); printf("%s","[1]... Eingabe\n"); printf("%s","[2]... Ausgabe\n"); printf("%s","[0]... Ende\n"); scanf("%d",&ein); if (ein=='\n') scanf("%d",&ein); switch (ein) { case 1: printf("%s","\nEingabe:\n\n"); printf("%s","Bitte geben Sie den Datensatz ein:\n"); scanf("%s",datensatz); eingabe(datensatz,help); break; case 2: ausgabe(help); break; case 0: break; default: fehler(); break; }; } return EXIT_SUCCESS; } void fehler() { printf("%s","\nFEHLER! Bitte wiederholen Sie die letzte Aktion\n\n"); } void eingabe(char datensatz[21], Ref help) { if (!help) { help=(Ref)malloc(sizeof(NODE)); help->left=(Ref)malloc(sizeof(NODE)); help->right=(Ref)malloc(sizeof(NODE)); help->left = help->right=NULL ; strcpy(help->info,datensatz); } else { if (strcmp(datensatz,help->info)<0) { help->left=(Ref)malloc(sizeof(NODE)); strcpy(help->left->info,datensatz); eingabe(datensatz,(help->left)); } if (strcmp(datensatz,help->info)>0) { help->right=(Ref)malloc(sizeof(NODE)); strcpy(help->right->info,datensatz); eingabe(datensatz,(help->right)); } } print(help); } void ausgabe(Ref help) { int eing=1; printf("%s","\nBitte waehlen Sie die Art der Ausgabe:\n\n"); printf("%s","[1]... Inorder\n"); printf("%s","[0]... Ende\n"); scanf("%d",&eing); switch(eing) { case 1: printf("%s","Inorder:\n"); help=root; inorder(help); break; default: break; }; } void inorder(Ref help) { if (help) { inorder(help->left); print(help); inorder(help->right); } getch(); } void print(Ref help) { printf("%s, \n",help->info); }
ich werde nicht ganz schlau aus dem programm, weil es mehrere unterschiedliche lösungsansätze für das problem gibt, und nicht eindeutig klar ist was du meinst:
a) kann es sein dass du an einigen stellen help und root verwechselt hast, bzw warum verwendest du nicht root ?
b) oder wolltest du ein call-by-reference erreichen (dafür spricht, dass du versucht help zu verändern, ohne in wahrheit das "original" beim aufruf zu verändern
c) beim einfügen in einen binärbaum: entweder du verzweigst rekursiv in einen der äste ODER du schreibst deinen neuen wert in den baum - nicht beides gleichzeitig.
auf der suche nach einem einfachen selbstgeschriebenen beispielprogram hab ich folgende code-stücke gefunden:
zeigt das einfügen in den baum, allerdings unter der annahme, daß malloc schon vor dem einfügen in den baum aufgerufen wurde. du siehst auch wie der call-by-reference nach strengen Ansi-C regeln gelöst wird: durch übergabe von pointern auf pointer (personptr*). in vielen modernen C-compilern kann man allerdings auch & in den funktionskopf aufnehmen und sich so ein bishen referenzerungs und dereferenzerungs-aufwand sparen.Code:typedef struct person *personptr; struct person { char name[30]; personptr kl,gr; // entspricht left und right }; void insert(personptr *wurzel,personptr element) { if (*wurzel) insert(strcmp((*wurzel)->name,element->name)<1? &(*wurzel)->kl:&(*wurzel)->gr,element); else *wurzel=element; }
Code:#include <string.h> #include <stdio.h> #include <stdlib.h> #define s strcmp typedef struct pr *p; struct pr {char n[30];p k,g;}; i(p*w,p e){(*w)?i(s((*w)->n,e->n)>0?&(*w)->k:&(*w)->g,e),e:[b][/b](*w=e);} a(p w){if(w)a(w->k),puts(w->n),a(w->g);} main(){p w=0,e; while(e=malloc(sizeof(struct pr)),e->k=e->g=0,*gets(e->n))i(&w,e); a(w);}
Zitat von atroxich werde nicht ganz schlau aus dem programm, weil es mehrere unterschiedliche lösungsansätze für das problem gibt, und nicht eindeutig klar ist was du meinst:
a) kann es sein dass du an einigen stellen help und root verwechselt hast, bzw warum verwendest du nicht root ?
b) oder wolltest du ein call-by-reference erreichen (dafür spricht, dass du versucht help zu verändern, ohne in wahrheit das "original" beim aufruf zu verändern
c) beim einfügen in einen binärbaum: entweder du verzweigst rekursiv in einen der äste ODER du schreibst deinen neuen wert in den baum - nicht beides gleichzeitig.
a & b) das passiert aber aus den oben erwähnten gründen nicht.
c) so ist es. du wanderst den baum entlang auf der suche nach einem freien platz und wenn du diesen gefunden hast, fügst du dein neues element ein.
ok danke ich glaube ich habe das problem irgendwie behoben...
es lebe die pfuscherei
nur hab ich jetzt wieder ein prob...
Code:FILE *filepointer; scanf("%s",filename); filepointer = fopen(filename, "r"); do { fscanf(filepointer,"%20s",info); print(info); }while(eof(filepointer==0)
while(feof(filepointer)==0)
bzw kurz:
while(!feof(filepointer))
//btw: was passiert, wenn die datei vollkommen leer ist ?
//edit: s/eof/feof/
wenn die datei leer ist...
if(!filepointer) printf("%s","Error\n");
else
{
...
}
das muss ich noch einbaun...
Danke atrox!
naja, nicht ganz, wirst aber noch draufkommen
ok das ist jetzt mein letztes Problem
[Linker error] undefined reference to `__gxx_personality_v0'
Im Borland C funzt das Prog, aber im Dev-C nicht
weiss wer warum der Linker Error ist?
falls du aus dem selben verzeichnis heraus compilierst wie mit borland-c, lösche vorher alle .obj dateien aus dem verz.
Zitat von atroxwhile(eof(filepointer)==0)
bzw kurz:
while(!eof(filepointer))
Zitat von FMFlashps: es könnte nicht schaden als 2. parameter von fopen "r+t" anzugeben (t steht für "open in text (translated) mode"
just my 0,02€
ZitatWG14/N843 Committee Draft -- August 3, 1998
The argument mode points to a string. If the string is
one of the following, the file is open in the indicated
mode. Otherwise, the behavior is undefined.)
r open text file for reading
w truncate to zero length or create text file for writing
a append; open or create text file for writing at end-of-file
rb open binary file for reading
wb truncate to zero length or create binary file for writing
ab append; open or create binary file for writing at end-of-file
r+ open text file for update (reading and writing)
w+ truncate to zero length or create text file for update
a+ append; open or create text file for update, writing at end-of-file
r+b or rb+ open binary file for update (reading and writing)
w+b or wb+ truncate to zero length or create binary file for update
a+b or ab+ append; open or create binary file for update, writing at end-of-file
Zitat von thatEs könnte schon schaden, weil "t" ist in keinem Standard definiert.
"b" schon, "t" nicht. Sagt zumindest mein Standard-Draft (siehe oben - die echte Version ist ja nicht frei erhältlich, aber angeblich praktisch identisch) und meine Linux man-Page.
ZitatThe mode string can also include the letter ``b'' either as a last
character or as a character between the characters in any of the two-
character strings described above. This is strictly for compatibility
with ANSI X3.159-1989 (``ANSI C'') and has no effect; the ``b'' is
ignored on all POSIX conforming systems, including Linux. (Other sys-
tems may treat text files and binary files differently, and adding the
``b'' may be a good idea if you do I/O to a binary file and expect that
your program may be ported to non-Unix environments.)
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025