Inhalt eines char Pointers konvertieren



  • noobLolo schrieb:

    versuch mal

    char TstNamPtrArr[][256] = { "hans", "FRANZ", "oTTo", "lisa-marie", "LISA MARIE" };
    statt
    char *TstNamPtrArr[10] = { "hans", "FRANZ", "oTTo", "lisa-marie", "LISA MARIE" };
    

    sich selbst zitieren ist normal nicht so mein fall...



  • Yoa, deswegen meine Verwirrung mit den Arrays.

    Wenn du

    char TstNamPtrArr[][256] = { "hans", "FRANZ", "oTTo", "lisa-marie", "LISA MARIE" };
    

    nimmst wie noobLolo schon meinte dann darfst du dort auch schreiben. Du kannst auch eine 10 statt 256 nehmen wenn es sein muss, allerdings funktioniert dann strlen nicht mehr wie oben beschrieben.

    Ach verdammt lolo war wieder schneller.



  • Ja, aber an dem Array darf ich nichts ändern, das ist fest so vorgegeben. Glaubt mir, ich mach's mit Absicht ungern schwerer als nötig. 😕



  • ja dann mach ne kopie davon du kannst machen was du willst und wirst nicht in das array schreiben dürfen...

    char *from[10] = {"asd","asd","asd"};
    char *to[10] = {};
    int l = 0;
    while( l<10 && from[l] != NULL ){
        to[l] = strdup(from[l]);
        l++;
    }
    

    oder so, kpl. ob das geht

    char *from[10] = {"asd","asd","asd"};
    int l = 0;
    while( l<10 && from[l] ){
        from[l] = strdup(from[l]);
        l++;
    }
    

    hatte ich schon wieder "einen" drin, das gibts doch nicht, hoffentlich sind da nicht noch mehr



  • Dann bleibt dir nichts anderes übrig als eine Kopie anzufertigen. Oder noch besser in place:

    for (int i = 0; i < 5; i++){
        char *string = malloc(strlen(TstNamPtrArr[i])+1);
        strcpy(string, TstNamPtrArr[i]);
        TstNamPtrArr[i] = string;
    }
    

    Alles bleibt beim alten, nur dass du jetzt die Strings überschreiben darfst.



  • noobLolo schrieb:

    ja dann mach ne kopie davon du kannst machen was du willst und wirst nicht in das array schreiben dürfen...

    Mit der einen oder anderen Systemfunktion(os-dependent) geht das.



  • Und mit irgendwelchen compilerahängigen Compilerflags gehts auch.



  • Okay, soweit hab ich's nun hinbekommen. Danke dafür.
    Das nächste Problem besteht darin, nicht mehr mit dem TestArray (das mit hans, franz , otto und lisa-marie) zu arbeiten, sondern den Benutzer selbst Namen eintragen zu lassen.

    Wie ist es möglich, in

    char **PtrNamPtrArr = NULL;
    

    selbst etwas herein zu speichern, sodass ich es wie TstPtrNamArr behandeln kann, unter der Voraussetzung fgets zu benutzen?



  • Namen mit fgets in einen char buf[NAMELEN_MAX] Puffer einlesen.
    strlen(buf)+1 Bytes mit malloc reservieren und den Zeiger in char name* speichern. Den Namen aus dem Puffer kopieren. Das char** Array um ein Element wachsen lassen und den Zeiger name darin speichern.



  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void) {
    	char **PtrNamPtrArr = NULL;
    	int i = 10;
    	PtrNamPtrArr = malloc(
    			 (sizeof(char*)*i)      //array
    			+(sizeof(char)*256*i)  //strings
    	);
    	char *buffer = (char*)(PtrNamPtrArr+(sizeof(char*)*i));
    	if(PtrNamPtrArr){
    		while(i--){
    			PtrNamPtrArr[i] = (buffer+i*((sizeof(char)*256)));
    		}
    		i=10;
    		while(i--){
    			 fgets(PtrNamPtrArr[i],255,stdin);
    			 PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0';
    		}
    		i=10;
    		while(i--){
    			 printf(PtrNamPtrArr[i]);
    		}
    	}
    	return 0;
    }
    

    hoffe da sind keine all zu großen schnitzer drin 😞



  • z.11 und 12 tauschen 😡



  • noobLolo schrieb:

    hoffe da sind keine all zu großen schnitzer drin 😞

    Wird schon reichen Puffer sind ja mal ganz nützlich, man kann es aber auch übertreiben 😃



  • char **PtrNamPtrArr = NULL;
        int i = NamAnz;
        PtrNamPtrArr = (char**) malloc((sizeof(char*)*i)+(sizeof(char)*MAXANZ*i));
        char *buffer = (char*)(PtrNamPtrArr+(sizeof(char*)*i));
        if(PtrNamPtrArr){
            while(i--){
                PtrNamPtrArr[i] = (buffer+i*((sizeof(char)*MAXANZ)));
            }
            i=NamAnz;
            while(i--){
                 fgets(PtrNamPtrArr[i],MAXANZ,stdin);
                 PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0';
            }
            i=NamAnz;
            while(i--){
                 printf(PtrNamPtrArr[i]);
            }
        }
    

    Hab das jetzt so angepasst, dass es nicht sofort abstürzt ((char**) vor malloc) und angepasst, dass man Anfangs eine Zahl (NamAnz) eingibt, die die Anzahl der einzutragenden Namen steuert. Problem ist er lässt mich nur NamAnz-1 eintragen, den letzten Namen nimmt er einfach als leer mit. Ansonsten blicke ich den Code auch nicht wirklich durch, falls du den etwas erklären könntest wär das super!



  • also ich hatte mir das so vorgestellt, gehen wir mal von dem alten teil aus
    char *xxx[10];
    das heißt wir brauchen speicher für 10 zeiger auf einen string, und dann brauchen wir noch speicher für die strings, in oberem fall hat jeder string eine unterschiedliche länge das ist aber jetzt erstmal gleich, also hab ich einfach mal 256 als länge genommen, dann hätte man 2 möglichkeiten das zu lösen erste

    char **PtrNamPtrArr = NULL;
    //wir holen uns speicher für ein array mit 10 char* zeiger
    PtrNamPtrArr = malloc(sizeof(char*)*10);
    //jetzt haben wir speicher für unser array aber keinen speicher für die
    //strings, den brauchen wir auch also...
    int l=10;
    while(l--){
      PtrNamPtrArr[l] = malloc(sizeof(char)*256);
    }
    //und jetzt haben wir alles was wir brauchen das ist eigentlich die saubere
    //variante und das sollte man auch so machen, wir brauchen aber jetzt 11*malloc
    //und das wollte ich mir schenken indem ich mir mit einem malloc den speicher
    //in einem stück hol und mir das dann selbst aufteil
    

    die zweite variante hast ja schon;)



  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void) {
      char **PtrNamPtrArr = NULL;
      int  nameLength = 255;
      int  arrayLength = 10;
      int  i = arrayLength;
      char *buffer;//könnte man auch weglassen da es sich nicht ändert
    
      //malloc castet man nur in c++ da bist aber im falschen unter forum;)
      //wir holen uns den gesamten speicher für die strings und das array
      PtrNamPtrArr = malloc(
         (sizeof(char*) * arrayLength)
        +(sizeof(char)  * arrayLength * nameLength)
      );
      if(PtrNamPtrArr != NULL){
        buffer = (char*)(PtrNamPtrArr+sizeof(char*) * arrayLength);
        //buffer zeigt jetzt auf den ersten wert nach dem array
        //jetzt weisem wir dem array den speicher für die strings zu
        while(i--){
          PtrNamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength));
        }
        i=arrayLength;
        while(i--){
          fgets(PtrNamPtrArr[i],nameLength-1,stdin);
          //fgets nimmt '\n' mit das machen wir wieder weg...
          PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0';
        }
        i=arrayLength;
        while(i--){
          printf(PtrNamPtrArr[i]);
        }
      }
    }
    

    weiß nicht ob dir das weiter hilft aber ich weiß auch nicht wie ich das erklären soll 😕



  • Wenn ich den Malloc nicht caste, bekomme ich aber folgenden Fehler:

    Error 7 error C2440: '=' : cannot convert from 'void *' to 'char *[]'

    Bei der Zeile:

    NamPtrArr = malloc(
         (sizeof(char*) * arrayLength)
        +(sizeof(char)  * arrayLength * nameLength)
      );
    

    Wenn ich den Malloc (char**) caste kompiliert es. Aber das Problem, dass wenn ich 3 Namen eingeben will, nur 2 eintragen kann, bleibt. 😕



  • Etwas das ich jetzt absolut nicht nachvollziehen kann:

    Anzahl der Namen: 3
    
    01Timo
    2Katze
    3Hund
    
    01Timo2Katze3Hund
    
    Ausgabe 1: Namen in Original-Reihenfolge und Original-Schreibweise
    
    Name  1:
    Name  2: Timo
    Name  3: Katze
    
    weiter mit [return]:
    

    Ist die (nachträglich formatierte Ausgabe von folgendem Code)

    int  nameLength = MAXANZ;
      int  arrayLength = NamAnz;
      int  i;
      char *buffer;//könnte man auch weglassen da es sich nicht ändert
    
      //malloc castet man nur in c++ da bist aber im falschen unter forum;)
      //wir holen uns den gesamten speicher für die strings und das array
      PtrNamPtrArr = (char**) malloc((sizeof(char*)*arrayLength)+(sizeof(char)*arrayLength*nameLength));
    
      if(PtrNamPtrArr != NULL){
        buffer = (char*)(PtrNamPtrArr+sizeof(char*) * arrayLength);
        //buffer zeigt jetzt auf den ersten wert nach dem array
        //jetzt weisem wir dem array den speicher für die strings zu
        for(i = 0; i <= arrayLength; i++){
          PtrNamPtrArr[i] = (buffer + i * (sizeof(char) * nameLength));
        }
        for(i = 0; i <= arrayLength; i++){
          printf("%d", i); fgets(PtrNamPtrArr[i],nameLength,stdin);
          //fgets nimmt '\n' mit das machen wir wieder weg...
          PtrNamPtrArr[i][strlen(PtrNamPtrArr[i])-1] = '\0';
        }
        for(i = 0; i <= arrayLength; i++){
          printf("%d", i); printf(PtrNamPtrArr[i]);
        }
      }
    

    Und ich verstehe einfach nicht, wieso er das erste fgets einfach nicht ausführt, sondern überspringt?



  • also bei mir klappts schon würde allerdings in den for schleifen < statt <= schreiben?

    nameLength = ist der länge des namens
    arrayLength = die anzahl an namen



  • achso und in z.18 hatte ich nameLength-1 weil ich verhindern wollte das jemand meine letzte 0 überschreiben kann...



  • Ich kann tun was ich will, das erste fgets überspringt er/ignoriert er, keine Ahnung was er macht. Und ich kann mir nicht erklären wieso. Egal ob ich jetzt <= in den for-Schleifen oder < mache. Die Namen dürfen maximal 50 Zeichen lang sein, das haben wir mit einer #define MAXANZ auf 51 oben schon geklärt und NamAnz wird beim Programmstart von der Tastatur per scanf eingelesen.

    Wenn ich jetzt 3 in NamAnz eingebe, dann startet die Eingabe-Schleife und gibt, statt auf eine Eingabe von fgets zu warten, sofort 0 und 1 aus. Also im Schleifendurchlauf in dem i = 0 ist, wartet fgets nicht auf eine Parametereingabe, sondern springt einfach weiter. Das Programm wartet erst bei i = 1 auf eine Namenseingabe. Dadurch hab ich insgesamt 4 Namen, von denen der erste leer ist und nur die letzten 3 eingegeben sind. Aber der Array muss ja von 0 an aufgefüllt sein.

    Keine Ahnung wie das weitergeht jetzt.


Anmelden zum Antworten