Zum Inhalt springen

Daten in Arbeitsspeicher schreiben, ausgeben und in eine Datei schreiben


Kadaj

Empfohlene Beiträge

Hallo,

ich versuche grad ein Programm zu schreiben, welches Namen von stdin einliest und diese dann in eine, von mir angelegte Struktur, einsortiert. Diese Daten lasse ich nach jedem Schreiben ausgeben und am Ende. So richtig funktioniert das aber noch nicht, ich fummel schon eine Weile am Code herum, aber es wird nicht besser. Hier erstmal der Quellcode:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct sort
{
char *data;
struct sort *l;
struct sort *r;
}sort;

sort *tree;
sort init={};

void add(sort *tree,char *data)
{

if(tree->data==NULL)
{
tree->data=data;
}
else
{
if(strcmp(data,tree->data)<0) // data ist kleiner, nach links
{ // rücke nach links
if(tree->l==NULL)
{
tree->l=malloc(sizeof(sort)); // Speicher reservieren
*(tree->l)=init; // initialisieren mit struct sort
}
add(tree->l,data); // Rekursion, bis Elememt eingetragen wird
}
else // data ist größer, also nach rechts damit
{
if(tree->r==NULL)
{
tree->r=malloc(sizeof(sort)); // Speicher reservieren
*(tree->r)=init; // initialisieren mit struct sort
}
add(tree->r,data); // Rekursion, bis Elememt eingetragen wird
}
}
printf("bisheriger Baum:\n");
printtree(tree);
}
void log(FILE *file)
{
if(tree->data!=NULL) // Name vorhanden?
{
fprintf(file,tree->data); // Name nach stdout schreiben
log(tree->r); // Funktion rekursiv für rechtes Element aufrufen
log(tree->l); // Funktion rekursiv für linkes Element aufrufen
}
}


int main(int argc,char *argv[])
{
FILE *file; // Pointer für Logfile
char puffer[64]; // Array für Namens-Eingabe

tree=malloc(sizeof(sort)); // Speicher reservieren
*tree=init; // initialisieren mit struct sort

if(argc!=2)
{
perror("usage: <program> <logfile>");
exit(EXIT_FAILURE);
}

file=fopen(argv[1],"a+t");
if(file==NULL)
{
perror("erro: open file");
exit(EXIT_FAILURE);
}

while(strcmp(puffer,"qq")!=0)
{
printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n");
fgets(puffer,64,stdin);
puffer[strlen(puffer)-1]=0;

if(strcmp(puffer,"qq")!=0)
add(tree,puffer);
}

printf("Hier die Ausgabe für den gesamten Baum:\n");
printtree(tree);

log(file); // Baum in die Logfile schreiben

fclose(file);
return 0;
}
[/PHP]

Also, das Programm sortiert die Namen alphabetisch wie in einem Binärbaum ein. Soll es zumindest, das passiert, wenn ich es ausführe:

[PHP]
./tree log.txt
Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:
Anna
bisheriger Baum:
Anna
Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:
Bob
bisheriger Baum:
Bob
bisheriger Baum:
Bob
Bob
Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:
qq
Hier die Ausgabe für den gesamten Baum:
qq
qq
Speicherzugriffsfehler

Er scheint die schon vorhandenen structs in data immer mit der aktuellen Eingabe zu überschreiben, keine Ahnung wieso.

Der Speicherzugriffsfehler kommt vom schreiben in die Datei, da haut auch was noch nicht so richtig hin.

Sieht jemand warum das Einsortieren nicht funktioniert?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moment, ich seh grade, dass ich eine Funktion nicht mit rüber kopiert ( printtree ) habe, wie ungeschickt. So sieht es vollständig aus:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct sort
{
char *data;
struct sort *l;
struct sort *r;
}sort;

sort *tree;
sort init={};

void add(sort *tree,char *data)
{

if(tree->data==NULL)
{
tree->data=data;
}
else
{
if(strcmp(data,tree->data)<0) // data ist kleiner, nach links
{ // rücke nach links
if(tree->l==NULL)
{
tree->l=malloc(sizeof(sort)); // Speicher reservieren
*(tree->l)=init; // initialisieren mit struct sort
}
add(tree->l,data); // Rekursion, bis Elememt eingetragen wird
}
else // data ist größer, also nach rechts damit
{
if(tree->r==NULL)
{
tree->r=malloc(sizeof(sort)); // Speicher reservieren
*(tree->r)=init; // initialisieren mit struct sort
}
add(tree->r,data); // Rekursion, bis Elememt eingetragen wird
}
}
printf("bisheriger Baum:\n");
printtree(tree);

}void printtree(sort *tree)
{
if(tree) // Name vorhanden?
{
puts(tree->data); // Name nach stdout schreiben
printtree(tree->r); // Funktion rekursiv für rechtes Element aufrufen
printtree(tree->l); // Funktion rekursiv für linkes Element aufrufen
}
}


void log(FILE *file)
{
if(tree->data!=NULL) // Name vorhanden?
{
fprintf(file,tree->data); // Name nach stdout schreiben
log(tree->r); // Funktion rekursiv für rechtes Element aufrufen
log(tree->l); // Funktion rekursiv für linkes Element aufrufen
}
}

int main(int argc,char *argv[])
{
FILE *file; // Pointer für Logfile
char puffer[64]; // Array für Namens-Eingabe

tree=malloc(sizeof(sort)); // Speicher reservieren
*tree=init; // initialisieren mit struct sort

if(argc!=2)
{
perror("usage: <program> <logfile>");
exit(EXIT_FAILURE);
}

file=fopen(argv[1],"a+t");
if(file==NULL)
{
perror("erro: open file");
exit(EXIT_FAILURE);
}

while(strcmp(puffer,"qq")!=0)
{
printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n");
fgets(puffer,64,stdin);
puffer[strlen(puffer)-1]=0;

if(strcmp(puffer,"qq")!=0)
add(tree,puffer);
}

printf("Hier die Ausgabe für den gesamten Baum:\n");
printtree(tree);

log(file); // Baum in die Logfile schreiben

fclose(file);
return 0;
}

[/PHP]

Überleg mal genau, wohin der Zeiger in deiner Struktur zeigt.

Wenn ich nur deinen Blick hätte ;) ... Nun, in der Funktion add wird überprüft ob ein Eintrag in der übergebenen Struktur von Typ sort in data vorhanden ist. Wenn nicht, dann wird dem Zeiger auf data(in der Struktur) den Wert von data(des Array zugewiesen) ...

Ich glaub ich versteh nicht worauf du hinaus willst. In meiner Struktur sort hab ich einen Zeiger auf ein char-Array für die Namen und jeweils 2 auf genau die selbe Struktur sort, einmal für links und einmal für rechts. Ich seh nichts, was ich falsch dereferenziert haben könnte... hmmm...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ei, danke dir, daran hab ich ja garnicht gedacht. Ich dachte, das wäre richtig, weil ich mir den Inhalt des Pointers probehalber gleich hab ausgeben lassen. Dann muss ich ja einfach nur beide Pointer bei der Zuweisung dereferenzieren:


{
*(tree->data)=*data;
printf("datapointer nach füllen:\n %s \n",*(tree->data));
}
[/PHP]

Scheinbar habe ich Pointerarithmetik noch nicht ganz verstanden, denn nun ist meine Ausgabe:

[PHP]
# ./tree log
Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:
Anna
data-array:Anna
data-pointer:(null)
Speicherzugriffsfehler

Ich hab dem Pointer Speicher geserviert und den Wert von data zugewiesen, warum ist tree->data dann (null), :confused: das versteh ich grad nicht...

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

Also nen Freund hat mir mal unter die Arme gegriffen, so sieht das Ergebnis aus:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct sBinarySortedTree
{
char *data;
struct sBinarySortedTree *left;
struct sBinarySortedTree *right;
}tBinarySortedTree;



tBinarySortedTree init={0}; /* init vom Typ tBinarySortedTree mit 0 initialisieren */

tBinarySortedTree *create()
{
tBinarySortedTree *newTree = malloc(sizeof(tBinarySortedTree)); /* Speicher reservieren */
if( newTree )
*newTree = init;
return newTree;
}

void tree_log( tBinarySortedTree *tree, FILE *file )
{

if( !file || !tree )
return;
tree_log( tree->left, file );
if( tree->data )
fprintf( file, "%s\n", tree->data );
tree_log( tree->right, file );
}

void printTree( tBinarySortedTree *tree )
{
tree_log( tree, stdout );
}


void addName( tBinarySortedTree *tree, char *data )
{
if( !tree || !data )
return;
if(tree->data==NULL)
{
tree->data=data;
}
else
{
if(strcmp(data,tree->data)<0) /* data ist kleiner, nach links */
{
if(tree->left==NULL)
tree->left=create();
addName( tree->left, data );
}
else /* data ist größer, also nach rechts damit */
{
if(tree->right==NULL)
tree->right=create();
addName( tree->right ,data );
}
}
}

#define BUFF_SIZE 64

void createInputPuffer( char **puffer )
{
*puffer = malloc( BUFF_SIZE * sizeof( char ) );
if( !(*puffer) )
{
fprintf( stderr, "could not create puffer\n" );
exit(EXIT_FAILURE);
}
}

int main(int argc,char *argv[])
{
FILE *file; /* Pointer für Logfile */
char *puffer = 0; /* Array für Namenseingabe */
tBinarySortedTree *myTree = 0; /* Wurzel des Baumes */

if(argc!=2)
{
perror("usage: <program> <logfile>");
exit(EXIT_FAILURE);
}

myTree=create();
if( !myTree )
{
fprintf(stderr,"error:create Tree\n");
exit(EXIT_FAILURE);
}

createInputPuffer( &puffer );

while(strcmp(puffer,"qq")!=0)
{
printf("Geben Sie einen Namen ein. Zum Beenden 'qq' eingeben:\n");
fgets(puffer,BUFF_SIZE,stdin);
puffer[strlen(puffer)-1]=0;

if(strcmp(puffer,"qq")!=0) {
addName( myTree, puffer );
createInputPuffer( &puffer );
}
}

printf("\nHier die Ausgabe für den gesamten Baum:\n");
printTree( myTree );

file=fopen(argv[1],"a+");
if( !file )
{
fprintf(stderr, "error: open file: %s\n",argv[1]);
exit(EXIT_FAILURE);
}
tree_log( myTree, file );
fclose(file);
return EXIT_SUCCESS;
}
[/PHP]

Vielen Dank für die Hilfe :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...