Hilfe mit verketteter Liste oder bzw. eingabe mit getchar



  • Hallo Liebes Forum 🙂 ,

    ich versuche mir mit mingw und eclipse eine Funktion zu basteln, die mir einen String erstellt, also ein char Array mit genau der Länge die ich brauche.
    Dazu möchte ich eine einfach verkettete Liste verwenden und die Zeichen mit getchar aus der Konsole auslesen.
    Ich weiss jedoch nicht genau wo das Problem liegt, aber am Ende kommt nur Mist dabei raus. 😕
    Jedoch funktioniert die Rückgabe eines NULL-Pointers, wenn ich gar nichts eingebe und nur mit Enter bestätige.

    Schon mal ganz herzlichen Dank für Eure Hilfe 👍

    lg Smut0r

    #include<stdio.h>
    #include<stdlib.h>
    #include "functions.h"
    
    struct stringTree
    {
    	char eingBuch;								/*eingegebener buchstabe*/
    	struct stringTree *nextSheet;				/*pointer auf nächstes element der verk. Liste*/
    };
    
    char *createString(const char* text)
    {
    	char *newString = NULL;						/*pointer auf fertiges char array*/
    	struct stringTree *firstAdr = NULL;			/*pointer auf anfang der verk. Liste*/
    	struct stringTree *lastAdr;					/*pointer auf anfang der verk. Liste bzw vorheriges Element*/
    	struct stringTree *nextAdr;					/*pointer auf nächstes Element für vorheriges element*/
    	char c;
    	size_t treeSize = sizeof(struct stringTree);
    	int count = 0;								/*anzahl der buchstaben für fertiges char*/
    	int count2 = 0;								/*elemtent des char arrays beim einfügen der symbole*/
    
    	printf("%s", text);							/*anfordern von Text vom Benutzer*/
    
    	while((c = (char)getchar()) == '\n')		/*einlesen des ersten zeichens und ggf überspringen von '\n'*/
    	{
    
    	}
    
    	while((c!='\n') && (c != EOF))				/*aufnehmen der eingabe des nutzers zu einer verk. Liste*/
    	{
    		if(firstAdr == NULL)					/*erstellen des ersten elements der verk. Liste*/
    		{
    			lastAdr = malloc(treeSize);
    			lastAdr->eingBuch = c;
    			lastAdr->nextSheet = NULL;
    			firstAdr = lastAdr;
    			count++;
    		}
    		else									/*anhängen der weiteren Elemente der verk. Liste*/
    		{
    			nextAdr = malloc(treeSize);
    			nextAdr->eingBuch = c;
    			nextAdr->nextSheet = NULL;
    			lastAdr->nextSheet = nextAdr;
    			lastAdr = nextAdr;
    			count++;
    		}
    
    		c = (char)getchar();					/*einlesen des nächsten zeichens*/
    	}
    
    	printf("\n\n");								/*zwei Leerzeilen ausgeben*/
    
    	if(firstAdr != NULL)	/*ggf erzeugen des string wenn symbol eingegeben und freigeben der elemente*/
    	{
    		char stringArr[count +1];
    		newString = stringArr;
    
    		do
    		{
    			stringArr[count2] = firstAdr->eingBuch;
    			count2++;
    			nextAdr = firstAdr->nextSheet;
    			free(firstAdr);
    			firstAdr = nextAdr;
    		}while(firstAdr->nextSheet != NULL);
    
    		stringArr[count2] = '\0';
    	}
    	return newString;
    }
    


  • Ich korrigiere, seitdem ich

    while((c = (char)getchar()) == '\n')		/*einlesen des ersten zeichens und ggf überspringen von '\n'*/
    	{
    
    	}
    

    eingefügt habe, kann ich natürlich nicht mehr mit Enter einen NULL-Pointer zurück geben 😉

    lg Smut0r



  • smut0r schrieb:

    ich versuche mir mit mingw und eclipse eine Funktion zu basteln, die mir einen String erstellt, also ein char Array mit genau der Länge die ich brauche.
    Dazu möchte ich eine einfach verkettete Liste verwenden und die Zeichen mit getchar aus der Konsole auslesen.

    Ich hoffe, just for fun!? 😮

    Warum castest du den Rückgabewert von getchar() und verwendest nicht stattdessen den richtigen Typtm für c ?
    c != EOF ... EOF hat in einem char garnicht Platz.
    Warum hast du so vieles in deinem if - else in der Schleife das in beiden Fällen dasselbe ist?
    Es ist schon spät ... aber wenn ich mich nicht ganz täusche leckt deine Freigabeschleife das letzte Element der Liste.
    Und zu allerguterletzt gibst du indirekt über newString die Adresse des Funktionslokalen Arrays stringArr zurück das aufhört zu existieren, sobald die Funktion verlassen wird.



  • Hallo,

    dank Dir für die Hilfe 🙂

    ja ist nur um das gelernte nicht ganz zu vergessen 😉

    ich habe es jetzt anders versucht, Einlesen funtioniert (ausser in eclipse),
    aber mein mit malloc in der letzten if schleife erzeugtes "char arry" wird scheinbar nicht richtig übergeben/erstellt whatever 😕

    #include <stdio.h>
    #include <stdlib.h>
    #include "someFunctions.h"
    
    struct stringTree
    {
    	int eingBuch;								/*eingegebener buchstabe*/
    	struct stringTree *nextSheet;				/*pointer auf nächstes element der verk. Liste*/
    };
    
    void createString(const char* printText, char* rueckArr)
    {
    	rueckArr = NULL;
    	size_t listenBlattGroesse = sizeof(struct stringTree);				/*zur allocation von speicher für ein neues listenelement*/
    	int c;																/*zum einlesen eines zeichens*/
    	struct stringTree *firstAdress = NULL;								/*adresse des listenanfangs*/
    	struct stringTree *lastAdress = NULL;								/*adresse des vorherigen elements*/
    	struct stringTree *nextAdress = NULL;								/*adresse des nächsten elements*/
    	int countSymbols = 0;												/*anzahl der buchstaben des strings ohne endzeichen*/
    	int countLoop = 0;													/*zum eintragen in arry*/
    
    	printf("%s", printText);											/*fordert user zur eingabe auf*/
    
    	c = getchar();														/*liesst erstes zeichen ein*/
    
    	while((c != '\n') && (c != '\0'))									/*falls symbole eingegeben lese ein*/
    	{
    		if(firstAdress == NULL)												/*erstelle ggf ersten eintrag*/
    		{
    			firstAdress = malloc(listenBlattGroesse);
    			firstAdress->eingBuch = c;
    			firstAdress->nextSheet = NULL;
    			lastAdress = firstAdress;
    			countSymbols++;
    		}else																/*ansonsten erstelle weitere einträge*/
    		{
    			nextAdress = malloc(listenBlattGroesse);
    			nextAdress->eingBuch = c;
    			nextAdress->nextSheet = NULL;
    			lastAdress->nextSheet = nextAdress;
    			lastAdress = nextAdress;
    			countSymbols++;
    		}
    
    		c = getchar();														/*solange kein return lese string ein*/
    		/*printf("%c", c);*/
    	}
    
    	/*in der verketteten liste steht nun string ohne endzeichen*/
    
    	if(firstAdress != NULL)												/*falls text eingegeben erstelle string und gebe speicher frei*/
    	{
    		rueckArr = malloc(sizeof(int)*(countSymbols+1));					/*erstellt speicher für string*/
    		while(firstAdress->nextSheet != NULL)
    		{
    			rueckArr[countLoop] = firstAdress->eingBuch;
    			nextAdress = firstAdress->nextSheet;
    			free(firstAdress);
    			firstAdress = nextAdress;
    			countLoop++;
    		}
    		rueckArr[countLoop] = '\0';											/*fügt endzeichen hinzu*/
    	}
    
    	printf("\n\n");														/*gebe zwei leerzeilen aus*/
    }
    


  • Du brauchtest nur c als int definieren. eingBuch als char ist ok.
    (und beim malloc für rueckArr ist das int auch falsch)

    Der Rückgabetyp von getchar ist ein int , damit neben allen Zeichen auch das EOF als Wert möglich ist.
    Danach kannst du mit char weiterarbeiten.
    (Aber das EOF hast du jetzt auch entfernt)

    Du hast jetzt leider bei createString den Rückgabetyp geändert (entfernt).
    Dadurch bekommst du nicht so einfach rueckArr aus der Funktion wieder raus.
    (Das war zuviel geändert).

    Was meinst du mit if-Schleife?

    Rätst du nur oder glaubst du zu wissen was du tust?



  • Ahhh Danke für den Anstoß, dass ich ja den Zeiger übergeben wollte (als Rückgabetyp) und nicht den Inhalt einer Adresse ändern, die ich übernehme 🙄

    Musste nur wieder etwas rein kommen 😉 , aber jetzt geht es, also Danke 👍

    #include <stdio.h>
    #include <stdlib.h>
    #include "someFunctions.h"
    
    struct stringTree
    {
    	int eingBuch;								/*eingegebener buchstabe*/
    	struct stringTree *nextSheet;				/*pointer auf nächstes element der verk. Liste*/
    };
    
    char* createString(const char* printText)
    {
    	char *rueckArr = NULL;
    	size_t listenBlattGroesse = sizeof(struct stringTree);				/*zur allocation von speicher für ein neues listenelement*/
    	int c;																/*zum einlesen eines zeichens*/
    	struct stringTree *firstAdress = NULL;								/*adresse des listenanfangs*/
    	struct stringTree *lastAdress = NULL;								/*adresse des vorherigen elements*/
    	struct stringTree *nextAdress = NULL;								/*adresse des nächsten elements*/
    	int countSymbols = 0;												/*anzahl der buchstaben des strings ohne endzeichen*/
    	int countLoop = 0;													/*zum eintragen in arry*/
    
    	printf("%s", printText);											/*fordert user zur eingabe auf*/
    
    	c = getchar();														/*liesst erstes zeichen ein*/
    
    	while((c != '\n') && (c != '\0'))									/*falls symbole eingegeben lese ein*/
    	{
    		if(firstAdress == NULL)												/*erstelle ggf ersten eintrag*/
    		{
    			firstAdress = malloc(listenBlattGroesse);
    			firstAdress->eingBuch = c;
    			firstAdress->nextSheet = NULL;
    			lastAdress = firstAdress;
    			countSymbols++;
    		}else																/*ansonsten erstelle weitere einträge*/
    		{
    			nextAdress = malloc(listenBlattGroesse);
    			nextAdress->eingBuch = c;
    			nextAdress->nextSheet = NULL;
    			lastAdress->nextSheet = nextAdress;
    			lastAdress = nextAdress;
    			countSymbols++;
    		}
    
    		c = getchar();														/*solange kein return lese string ein*/
    		/*printf("%c", c);*/
    	}
    
    	/*in der verketteten liste steht nun string ohne endzeichen*/
    
    	if(firstAdress != NULL)												/*falls text eingegeben erstelle string und gebe speicher frei*/
    	{
    		rueckArr = malloc(sizeof(char)*(countSymbols+1));					/*erstellt speicher für string*/
    		do
    		{
    			rueckArr[countLoop] = (char)firstAdress->eingBuch;
    			nextAdress = firstAdress->nextSheet;
    			free(firstAdress);
    			firstAdress = nextAdress;
    			countLoop++;
    		}while(firstAdress != NULL);
    		rueckArr[countLoop] = '\0';											/*fügt endzeichen hinzu*/
    	}
    
    	printf("\n\n");														/*gebe zwei leerzeilen aus*/
    
    	return rueckArr;
    }
    

Anmelden zum Antworten