Pointer vom Typ char im Array ansprechen



  • die funktion toupper habe ich nicht selbst geschrieben: toUpper cpp.com

    Vielleicht sollte ich noch folgendes ergänzen:

    die funktion ConvertNamen wird in main aufgerufen und das geschiet so:

    int main(int argc, char *argv[])
    {
      /* Deklaration von Variablen */
      /*****************************/
      char * TstNamPtrArr[10] = {"hans","FRANZ","oTTo","lisa-marie","LISA MARIE"};
      int    NamAnz           = 5;
    
      /* Hilfs- und Schleifenvariablen                                            */
      char   dummy[81];                 /* Dummyfeld um Programm anzuhalten       */
    
      ConvertNamen( TstNamPtrArr, NamAnz );
    
      gets(dummy);
      return 0;
    }
    

    Also das übergebene Array ist wiederum ein Pointer auf Array, ist das richtig?!

    Fehlermeldung bekomme ich keine (außer wenn du die Windows Fehlermeldung: "Das Programm funktioniert nicht mehr" meinst 🙂 ) Ich schätze mal, das liegt daran, dass ich in irgendein Speicherbereich schreibe, in den man lieber nicht schreiben sollte, kann das sein?

    mfg, brc



  • Nachtrag: Was mich ebefalls wundert:

    folgendes geht:

    NamPtrArr[aktNam] = "Test";
    

    folgendes geht nicht:

    NamPtrArr[aktNam][aktChar] = "T";
    

    oder

    NamPtrArr[aktNam][aktChar] = 'T';
    


  • Du versuchst, Stringkonstanten...

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

    ...zu modifizieren. Das ist nicht erlaubt. Das Verhalten ist daher undefiniert (in Deinem Fall stürzt das Programm ab).

    int main()
    {
        char  buffer[5][16];
        char* beg_ptr[5];
    
        size_t n;
    
        //konstante Literale in variable Arrays kopieren
        strcpy(buffer[0], "hans");
        strcpy(buffer[1], "FRANZ");
        strcpy(buffer[2], "oTTo");
        strcpy(buffer[3], "lisa-marie");
        strcpy(buffer[4], "LISA MARIE");
    
        //weil char[n][m] != char** ist
        for(n = 0; n != 5; ++n)
        {
            beg_ptr[n] = buffer[n];
        }
    
        ConvertNamen(beg_ptr, 5);
    }
    


  • hi,

    was meinst du mit Stringkonstanten zu modifizieren?

    Das seltsame ist, dass uns der Prof. die main genau so vorgegeben hat und auch der Funktionsaufruf in der main soll exakt so sein. Nur die Implementierung der Funktion sollen wir selbstgestalten...

    Aber wenn du sagst, ich versuche illegaler weise eine Stringkonstante zu bearbeiten, wieso kann ich dann den kompletten Inhalt eines Arrayelementes ändern? siehe:

    NamPtrArr[aktNam] = "Test";
    

    mfg, brc



  • Sowas

    "test"
    

    ist eine Stringkonstante, die man (wie der Name Konstante schon impliziert) nicht modifizieren darf.



  • brc schrieb:

    Aber wenn du sagst, ich versuche illegaler weise eine Stringkonstante zu bearbeiten, wieso kann ich dann den kompletten Inhalt eines Arrayelementes ändern? siehe:

    NamPtrArr[aktNam] = "Test";
    

    mfg, brc

    Weil Du damit nich versuchst einen einzelnen Charakter einer Stringkonstanten zu ändern, sondern einen Zeiger umhängst auf einen anderen konstanten String.

    Der Ausdruck

    char * TstNamPtrArr[10]...
    

    definiert ein Array auf char* mit 10 Elementen. 5 Elemente weist Du zu. Die 5 zugewiesenen Elemente sind dabei String-Literale, und die darf man nicht ändern.
    Wenn Du denn sagst

    NamPtrArr[aktNam] = "Test";
    

    dann zeigt der char* mit dem Index aktNam nicht mehr auf das alte Literal, sondern auf das Literal "Test". Aber auch hier darfst Du wieder keine Elemente ändern.



  • OK,

    dann war das wohl ein falscher Ansatz. Aber dann bin ich etwas ratlos, wie ich das Problem sonst angehen soll. So wie ich das verstanden habe, wird der Funktion ConvertNamen nicht einfach ein Array übergeben, sondern ein Zeiger auf ein Array, damit man dieses bearbeiten kann (Call-by-Reference?).

    Würde das ganze denn mit einem temporären char Array funktionieren, in die ich bei jedem Namen die richtigen Buchstaben speichere und dann am Schluss in das NamPtrArr Array speichere?

    Wie sieht es da mit der funktion strcpy aus, könnte man da etwas machen?

    mfg, brc



  • Um zu testen, ob das Programm ohne den vom Prof eingeführten Fehler (:D) funktioniert, kannst Du Tachyons Methode oder die Funktion strdup verwenden. Dazu definiere das Array im main wie folgt:

    char * TstNamPtrArr[10] = {
    strdup("hans"),
    strdup("FRANZ"),
    strdup("oTTo"),...
    };
    

    Die Funktion strdup ist zwar kein ANSI C, aber unter fast allen System in <string.h> zu finden. Sollte das doch nicht der Fall sein, definiere die Funktion selbst:

    char* strdup( char const* s )
    {
        size_t l = strlen( s );
        char* r = malloc( l + 1 );
        memcpy( r, s, l + 1 );
        return r;
    }
    

    Die Strings in TstNamPtrArray müssten am Programmende mit free() wieder freigegeben werden, aber das können wir - für den Test - aussen vor lassen. Sollte Dein Programm damit funktionieren (im Gegensatz zur Variante mit dem Array aus Konstanten), kannst Du Deinem Prof erklären was er falsch gemacht hat.



  • hi,

    vielen dank für das Programm. Jetzt funktioniert es wunderbar.
    Hintergrund der ganzen Geschichte ist, dass wir in der Übung genau mit diesen Funktionen (malloc & calloc) arbeiten sollen, also dynamisch das ganze erzeugen. Allerdings sollten wir die Funktionen dann vorher mit einem Testarray programmieren, damit man sich danach auf die dynamisierung konzentrieren kann.

    Da er dieses testarray anscheinend als Hilfe gegeben hat, hat er es vermutlich danach nicht noch einmal extra damit programmiert. Und siehe da: ein kleiner Fehler schleicht sich ein.

    Aber eine Frage habe ich noch: Wenn ich das ganze jetzt dynamisch erstelle, also die größe des Feldes über Zeiger, dann sollte es doch auch ohne deine Hilfsfunktion klappen, oder?

    mfg, brc



  • Moin,

    entschuldigt, wenn ich noch eine weiter Frage habe, aber ich komme nun bei einem anderem Problem nicht weiter:

    Die Eingabe der Namen soll dynamisch erfolgen. Also, es soll ein char Array mit einer bestimmten Anzahl von Feldern erstellt werden - für jeden Namen eins. Dann ist dieses eine Feld eines bestimmten Namens ebenso ein Char Feld mit dynamischer Länge: der Länge des Namens.
    Die funktion die das realisieren soll, heißt GetNamen.

    Im main wird Sie folgendermaßen aufgerufen:

    char ** PtrNamPtrArr = NULL;
      int     NamAnz;
      clrscr();
    
      printf(" Anzahl der Namen: "); scanf("%d",&NamAnz);
      ClrStdIn(); /* leert den Eingabepuffer */
      GetNamen( PtrNamPtrArr, NamAnz );
    

    Hier die Implementierung der Funktion:

    void GetNamen( char * NamPtrArr[], int NamAnz )
    {
      char   AktNam[NAMSTRLEN_MAX];
      char * PtrNam;
      int    iAktNamPtr;
      int    iEnd;
    
      for ( iAktNamPtr = 0; iAktNamPtr < NamAnz; iAktNamPtr++) {
    
        printf(" Name %2d: ", iAktNamPtr + 1);
        fgets( AktNam, NAMSTRLEN_MAX+1, stdin );
        iEnd = strlen(AktNam) - 1;
    
        if( AktNam[iEnd] == '\n' ) {
          AktNam[iEnd] = '\0';
          iEnd--;
        }
        else ClrStdIn();
    
        PtrNam = (char *) calloc( iEnd+2, sizeof(char) );
    
        strcpy( PtrNam, AktNam );
    
        NamPtrArr[iAktNamPtr] = PtrNam;
    
      }
    
    }
    

    Es hakt am letzen Befehl: "NamPtrArr[iAktNamPtr] = PtrNam;" Das Programm stürzt ab. Wenn ich die Fehlersuche aktiviere und Schrittweise ausführe, kommt in der letzten Zeile folgende Warnung:
    "Eine Zugriffsverletzung (Segmentation Fault) trat in Ihrem Programm aus."

    WIeso kann ich dem NamPtrArr mit dem Index iAktNamPtr nichts übergeben? Auch NamPtrArr[iAktNamPtr] = "Test"; funktioniert leider nicht.

    Es wäre super, wenn sich nochmal jemand das Problem anschauen könnte, natürlich nur, wer Zeit und Lust hat 🙂

    Vielen dank!

    mfg, brc


Anmelden zum Antworten