String in Grossbuchstaben wandeln, aber ich kapiers nicht...



  • Hallo!

    Ich will einen kompletten String in Großbuchstaben umwandeln.

    Ich bin jetzt mit soweit, daß ich folgendes zsammenprogrammiert habe (s.U.), aber es klappt nicht und ich habe nicht den geringsten Schimmer warum.

    Im Netz habe ich auch eine Lösung gefunden die auf String[i] die entsprechenden ASCII-Werte draufaddiert bzw. subtrahiert, aber der Effekt ist derselbe.

    Ciao

    OkkaPapa

    P.S. muß ich das wirklich Zeichenweise machen oder gibts da auch was von RatioPharm?? 🙂

    char* StrToUpper(char* String)
    {
      int i;
      int len=strlen(String);
    
      for (i=0;i<len;i++){
    
        if (String[i] >= 'a' && String[i] <='z'){
    
           //printf("%c\n",String[i]);
           String[i]=toupper(String[i]);
    
        }
    
      }
    
      return String;
    }
    


  • Wie stellst du fest, dass es nicht klappt?

    Zeig mal dein (minimales) main

    Für den Test auf Kleinbuchstaben gibt es auch islower (sogar mit Beispiel)


  • Mod

    Mir schwant böses. An sich kann dieser Code funktionieren, aber wie du mit der Zeichenkette umgehst (insbesondere die Rückgabe) lässt mich ahnen, dass du nicht wirklich weißt, was du da tust. Lass mich raten: Dein Aufruf der Funktion sieht wie folgt aus?

    char *ergebnis = StrToUpper("test");
    

    Und das funktioniert dann nicht?

    Das Problem ist, dass du hier die Zeichenketten so behandelst, als wäre die Zeichenkette selbst ein first-class object. Ist sie aber in C nicht. Du hantierst mit einem Zeiger auf ein Array aus chars. Den Zeiger kannst du kopieren und an die Funktion übergeben oder auch wieder heraus, aber die Zeichenkette selber nicht. Das heißt, was hier geschieht, ist, dass du die Originalzeichenkette veränderst und dann einen weiteren Zeiger auf die veränderte Zeichenkette aus der Funktion zurück gibst. Wenn du die Funktion aber wie oben aufrufst, dann ist die Originalzeichenkette jedoch ein Literal, eine Konstante. Aus historischen Gründen ist es möglich, diese Zeichenkettenliterale in Kontexten zu benutzen, in denen sie verändert werden können (z.B. Übergabe an deine Funktion), aber wenn tatsächlich Änderungen durchgeführt werden, ist das Ergebnis undefiniert. Meistens passiert gar nichts. Das ist das, was du beobachtest.

    Habe ich richtig geraten?



  • Hallo!

    DirkB schrieb:

    Wie stellst du fest, dass es nicht klappt?

    Ich bekomme einen SegFault

    Zeig mal dein (minimales) main

    Für den Test auf Kleinbuchstaben gibt es auch islower (sogar mit Beispiel)

    in main habe ich die Funktion schlichtweg erstmal mit

    StrToUpper("testTeSt");
    

    aufgerufen.

    Ciao

    OkkaPapa



  • Hast du den Beitrag von SeppJ verstanden?


  • Mod

    OkkaPapa schrieb:

    Ich bekomme einen SegFault

    Das ist dann die andere übliche Möglichkeit, was passieren kann, wenn man versucht, ein Zeichenkettenliteral zu ändern. Erklärung: Siehe meine erste Antwort.



  • DirkB schrieb:

    Hast du den Beitrag von SeppJ verstanden?

    Ich hatte zurückgepostet, ohne daß ich den Beitrag von JeppJ vorher gesehen habe...

    Ich gebe zu, daß ich nicht so ganz gerafft habe was er da beschreibt. Da werde ich mich mal tiefer mit befassen müssen... Strings sind in C für mich immer noch ein Buch mit sieben Siegeln.

    Ciao

    OkkaPapa



  • Der Text "testTeSt" steht ja irgendwo im Speicher. Allerdings ist dieser Speicherbereich für dich nicht beschreibbar.
    Daher der Fehler.

    Wenn der Text in einem Array steht, ist das Problem beseitigt

    char test[] = "testTeSt";
    StrToUpper(test);
    

    Der Text "testTeSt" steht auch hier irgendwo im Speicher. Er wird beim Anlegen vom Array test in dieses kopiert.
    Wenn du irgendwo im Programm z.B. einen Text hast, der "TeSt" lautet, kann dies der hintere Teil von "testTeSt" sein. Daher kannst/darfst du Stringliterale nicht verändern.



  • Der gcc kennt die Option -Wwrite-strings , die Dich in solchen Fällen warnt.

    void func(char* s){}
    
    int main(void){
      func("hallo");
    }
    
    cc -std=c11 -Wall -pedantic -g -Wwrite-strings    test.c   -o test
    test.c: In function ‘main’:
    test.c:4:3: warning: passing argument 1 of ‘func’ discards ‘const’ qualifier from pointer target type [enabled by default]
    test.c:1:6: note: expected ‘char *’ but argument is of type ‘const char *’
    

Anmelden zum Antworten