mit malloc ,Eingabe speichern

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
miskin
Beiträge: 14
Registriert: Mo Mai 12, 2014 10:42 am

mit malloc ,Eingabe speichern

Beitrag von miskin » Sa Mai 24, 2014 2:45 pm

Hi
brauche wieder eure Hilfe.
Meine Methode soll alle Eingaben meiner Shell speichern und das ganze soll mit malloc und realloc realisiert werden.

Code: Alles auswählen

#define BUF 255	
        size_t len;
	char *str_hist = NULL;
        char input[BUF];

void eingabe_einlesen() {
	int x =0;
	
	fgets(input,BUF,stdin);
	str_hist=malloc(strlen(input)+1);
	if (NULL==str_hist) {
                     printf("KEIN SPEICHER"); 
                     return EXIT_FAILURE;
        }
	strcpy(str_hist, input);
	len=strlen(str_hist);
	str_hist=realloc(str_hist,strlen(input)+len+1);
	if(NULL == str_hist) {
          printf("Kein virtueller RAM mehr vorhanden ... !");
          return EXIT_FAILURE;
       }
       strcat(str_hist, input);
.
.
.
	
und wenn ich meine Shell schließe rufe ich folgende Methode auf

Code: Alles auswählen

void schliessen() {
	
	printf("SCHLIESSEN %s",str_hist);  // Hier sollen eigentlich alle Eingabe ausgegeben werden
	free(str_hist);   
	exit(1);
}
leider gibt meine Shell nur den letzten Eintrag aus.
es soll aber alle Eingaben ausgeben.Spaeter soll das ganze in einer Datei gespeichert werden, wobe jedem Eintrag eine ID (0,1,2,...) vorangestellt werden soll.



LG miskin

FritziFoppel
Beiträge: 101
Registriert: Sa Mär 02, 2013 6:53 pm
Wohnort: Göppingen

Re: mit malloc ,Eingabe speichern

Beitrag von FritziFoppel » Sa Mai 24, 2014 3:55 pm

Tach,
ich bin mal kurz drübergeganen und ich meine, dass es am kopieren des strings liegt.

Code: Alles auswählen

strcpy(str_hist, input);
Wenn du deine Eingabe input machst, dann wird dein str_hist damit überschrieben und nicht dahinter angehängt. Deshalb siehst du auch nur deinen letzten Eintrag.
Wenn etwas nicht funtzt lass ich mir immer die Variablen ausgeben, wie z.B. strlen(input), strlen(str_hist), oder du gibts einfach den string aus, dann siehst du das er überschrieben wird.
Wenn die Eingaben am Ende eh in eine Datei geschrieben werden, dann kannst du nach jeder Eingabe in die Datei schreiben.

miskin
Beiträge: 14
Registriert: Mo Mai 12, 2014 10:42 am

Re: mit malloc ,Eingabe speichern

Beitrag von miskin » Sa Mai 24, 2014 4:42 pm

Hi
Danke erstmal!
Ja das ist einleuchtend ich müsste dann dafür sorgen, das die nächste Eingabe angehängt wird.
Da hab ich weiter unten mit strcat(str_hist, input); gemacht.
Nur jedesmal wenn die Methode aufgerufen wird geht er über strcpy(str_hist, input); und uberschreibt alles wieder.
Deinen Tipp mit strlen(str_hist) hat ergeben, das die Länge der gesammten Eingaben entspricht.
Ich versuche mal mit einem counter irgendwie strcpy(str_hist, input); bei der 2ten Eingabe zu überspringen und direkt strcat(str_hist, input); aufzurufen.
Melde mich dann wieder.
LG miskin

Nemo
Beiträge: 37
Registriert: Sa Mär 02, 2013 3:18 pm

Re: mit malloc ,Eingabe speichern

Beitrag von Nemo » Sa Mai 24, 2014 4:53 pm

Hi,
FritziFoppel hat recht, es liegt am kopieren des Strings, das lässt sich jedoch leicht lösen:

Code: Alles auswählen

    void eingabe_einlesen() {
       int x =0;
       
       fgets(input,BUF,stdin);
       // hier entfällt malloc
       if (NULL==input) { //Hier wird direkt input überprüft.
                         printf("KEIN SPEICHER");
                         return EXIT_FAILURE;
            }
       // hier entfällt strcpy
       len=strlen(str_hist);
       str_hist=realloc(str_hist,strlen(input)+len+1);
       if(NULL == str_hist) {
              printf("Kein virtueller RAM mehr vorhanden ... !");
              return EXIT_FAILURE;
           }
           strcat(str_hist, input);
    .
    .
    .
miskin hat geschrieben:Hi
Ja das ist einleuchtend ich müsste dann dafür sorgen, das die nächste Eingabe angehängt wird.
Da hab ich weiter unten mit strcat(str_hist, input); gemacht.
Nur jedesmal wenn die Methode aufgerufen wird geht er über strcpy(str_hist, input); und uberschreibt alles wieder.
Deinen Tipp mit strlen(str_hist) hat ergeben, das die Länge der gesammten Eingaben entspricht.
Ich versuche mal mit einem counter irgendwie strcpy(str_hist, input); bei der 2ten Eingabe zu überspringen und direkt strcat(str_hist, input); aufzurufen.
Melde mich dann wieder.
LG miskin
Da war ich wohl etwas langsam. Du brauchst keinen counter, da du auch strcpy(str_hist, input) nicht brauchst.

miskin
Beiträge: 14
Registriert: Mo Mai 12, 2014 10:42 am

Re: mit malloc ,Eingabe speichern

Beitrag von miskin » Sa Mai 24, 2014 10:09 pm

Hi

Dein Code verursacht bei mir ein Segmentation fault.
Man muss ja erst Speicher initialisieren, das geht ja mit malloc und realloc, ist dafür das wenn der
Speicher den man vorher mit malloc initialisiert hat voll ist, neuer Speicher zur verfügung gestellt wird.
Hab ich das richtig verstanden?

LG miskin

Nemo
Beiträge: 37
Registriert: Sa Mär 02, 2013 3:18 pm

Re: mit malloc ,Eingabe speichern

Beitrag von Nemo » So Mai 25, 2014 1:17 am

miskin hat geschrieben:Man muss ja erst Speicher initialisieren, das geht ja mit malloc und realloc, ist dafür das wenn der
Speicher den man vorher mit malloc initialisiert hat voll ist, neuer Speicher zur verfügung gestellt wird.
Hab ich das richtig verstanden?
Das stimmt soweit, jedoch wirkt realloc, wenn man einen NULL-Pointer übergibt, wie malloc. Das Problem ist allerdings tatsächlich dass der Speicher noch nicht initialisiert wurde, nämlich an dieser Stelle:

Code: Alles auswählen

       len=strlen(str_hist);
Beim ersten Aufruf der Funktion ist str_hist noch ein NULL-Pointer, mit dem strlen natürlich nichts anfangen kann. Das lässt sich leicht beheben:

Code: Alles auswählen

if(str_hist)
       len=strlen(str_hist);
Hier wird der Befehl einfach nicht ausgeführt, solange str_hist ein NULL-Pointer ist. Das ist zwar nicht die effizienteste Lösung, aber das sollte keine Rolle spielen.

Ich habe das Programm kompiliert und es funktioniert, allerdings treten manchmal Speicherzugriffsfehler bei der Funktion schliessen auf, die ich mir nicht erklären kann.

Antworten