Inhalt eines char Pointers konvertieren



  • ⚠ Da der Array bei 0 beginnt und bis 10 geht passt es rein. ⚠
    richtig ist
    Da der Array bei 0 beginnt und bis 9 geht passt es rein.
    int arr[10];

    erstes ist arr[0];
    letztes ist arr[9];

    Dürfen wir leider nicht, die Struktur diesbezüglich ist fest vorgegeben, wir dürfen selbst in den Unterprogrammen nur eingeschränkt arbeiten, wie wir wollen. :/
    

    also von sowas hab ich ja noch nie gehört... aber man lernt ja nie aus, du kannst auch eine kopie von deinem string array anlegen, alerdings würd ich das nicht in "ConvertNamen" mit ein bauen denn das gehört da nicht rein

    zum kopieren

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

    hoffe das klappt so...

    darüber hinaus ist es ja so das dein programm in zukunft sowieso die namen woanders hernehmen soll also entweder von der tastatur, einer datei, datenbank o.ä. und dann sind die strings idr. nicht schreibgeschützt.



  • "LISA MARIE" ist ein '\0'-terminierter String, deshalb brauchst du 11 chars, 10 für LISA MARIE und 1 fürs '\0'-Zeichen. Wahrscheinlich wird deshalb das '\0'-Zeichen geschluckt und dein Array sieht tatsächlich so aus:

    hans\0     FRANZ\0     oTTo\0     lisa-marieLISA MARIE
    

    Das würde auch erklären warum das nicht richtig läuft.
    strlen versagt hier weil es bei lisa-marie bis zum '\0'-Zeichen zählt, was aber garnicht da ist.
    Du kannst aber statt strlen(Name) einfach 10 hinschreiben, dann sollte es funktionieren.



  • @nwp2
    char *from[10] erstellt bei mir ein array für 10 char* zeiger ist doch bei dir auch so oder?



  • Ups, ich nehme alles zurück und behaupte das Gegenteil.



  • Ja, später sollen bis zu 10 Namen per fgets eingelesen werden. Vorerst sollen wir aber mit dem Test-Array die Unterprogramme zum Laufen kriegen. Hab jetzt zwar noch etwas weiter rumprobiert, aber finde einfach keine Lösung, wie das Programm nicht abstürzt, wenn ich versuche einzelne Buchstaben von "Name" anzusprechen (Name[0] z.B. was in dem Fall "h" von "hans" sein sollte).

    Sobald die Unterprogramme funktionieren, soll ein Feld mit char-Zeigern dynamisch per calloc erzeugt werden und ein Zeiger PtrNamPtrArr auf die Startaddresse zeigen. Das Feld soll dann genau NamAnz (1 bis max 10) Elemente vom Datentyp char* enthalten. Und in die Feldelemente kommen die Addressen der dynamischen Strings, die die Namen enthalten. Bin mir da zwar auch noch nicht 100% sicher wie das implementiert werden soll, aber erstmal will ich einfach nur dass es mit dem Test-Ding klappt.

    Also das hauptsächliche Problem gerade ist, dass ich aus der Unterfunktion nicht wirklich in den Ram speichern kann, weil er mir sofort 'ne AccessViolation andreht. Muss ich vielleicht doch vorher schon etwas mit calloc oder so machen?

    Und nochmal zum Verständnis: Wenn ich einen Zeiger (char *Name) erstelle und den mit NamPtrArr[0] gleichsetze (Name = NamPtrArr[0]), habe ich in "Name" den ersten Eintrag von NamPtrArr, also "hans" (gerade per fprint getestet). Wieso kann ich dann diesen String charakterweise nicht per Name[0] Schritt für Schritt durcharbeiten? Sobald ich einen Index anhänge kriege ich eine Access-Violation. Gibt es da noch eine andre Methode?



  • Kuh-Couch schrieb:

    Wieso kann ich dann diesen String charakterweise nicht per Name[0] Schritt für Schritt durcharbeiten?

    also lesen kannst du schon nur nicht schreiben weil das in einem schreibgeschützten bereich drin steht...



  • 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;)


Anmelden zum Antworten