Zeichenfolge in Großbuchstaben umwandeln (Funktion, Pointer,toupper)



  • Wann wird denn s inkrementiert?
    Wann wird der neue Wert dem *s zugewiesen?

    Du hast da zweimal *s stehen (links und rechts vom = )

    Erstmal muss ja der rechte Teil berechnet werden, bevor er der linken Seite zugewiesen wird. Dann ist evtl s aber schon erhöht worden.
    Oder hat der Compiler sich erst s gemerkt, bevor er dann die rechte Seite ausführt?

    Genau aus diesem Grund sind solche Konstrukte nicht erlaubt.



  • Da fällt es mir wie Schuppen aus den Haaren ...



  • *s = toupper(*s++);
    

    Das führt in doppelter Hinsicht zu undefiniertem Verhalten
    - toupper soll immer nur entweder unsigned char oder EOF erhalten (char kann signed char sein -> UB)
    - die gleiche Variable wird mehrfach evaluiert ohne einen sequencepoint zwischendurch, '=' ist entgegen landläufiger Meinung kein sequencepoint, dafür zwar ein Funktionsaufruf, toupper braucht aber keiner zu sein sondern ein Makro wobei dann bei macro(*s++) noch andere, meist ungewollte "Nebeneffekte" auftreten können

    Dürfte aber nicht den Absturz des Programms erklären, da hast du wohl noch weitere Fehler gemacht.



  • Funktionen zur Arbeit mit Zeichenketten:
    http://www.imb-jena.de/~gmueller/kurse/c_c++/c_fctstr.html

    Speziell und Dein Freund

    strupr
    
      #include <string.h>
    
      char *strupr(char *s);
    
    Konvertiert alle Kleinbuchstaben eines String in Großbuchstaben.
    strupr konvertiert die Kleinbuchstaben des durch s angegebenen Strings in Großbuchstaben.
    Dabei wird die Kategorie LC_TYPE der aktuellen Localei-Einstellung berücksichtigt.
    In der standardmäßigen Locale-Einstellung "C" werden die Buchstaben a bis z in die Buchstaben A bis Z konvertiert und alle anderen Zeichen (insbesondere die deutschen Umlaute) bleiben unverändert.
    
    Rückgabewert:
    strupr liefert s zurück.
    

    Beispiel leicht geändert aus MSDN:

    // This program uses strlwr and strupr to create
    // uppercase and lowercase copies of a mixed-case string.
    #include <string.h>
    #include <stdio.h>
    
    int main( void )
    {
       char string[100] = "The String to End All Strings!";
       char * copy1 = strdup( string ); // make two copies
       char * copy2 = strdup( string );
    
       strlwr( copy1 ); 
       strupr( copy2 );
    
       printf( "Mixed: %s\n", string );
       printf( "Lower: %s\n", copy1 );
       printf( "Upper: %s\n", copy2 );
    
       free( copy1 );
       free( copy2 );
    }
    

    Ausgabe

    Mixed: The String to End All Strings!
    Lower: the string to end all strings!
    Upper: THE STRING TO END ALL STRINGS!
    

    Aber simpler ist natürlich der loop mit toupper 😉


  • Mod

    strdup

    #include <string.h>

    char *strdup(const char *s);

    Kopiert einen String in einen neuen Speicherbereich.
    strdup bestimmt zuerst die Länge des übergebenen String s, reserviert danach mit malloc einen Speicherbereich entsprechender Größe (strlen(s) + 1) und kopiert den Inhalt von s in diesen neu reservierten Speicherbereich.
    Der Programmierer muß den Speicher selbst wieder freigeben, wenn dieser nicht mehr benötigt wird.

    Ihhh! So etwas macht man doch nicht!



  • Auch hier nochmal:

    strupr()
    

    Ist selbst in C11 noch nicht im Standard, und somit auch nicht in <string.h>

    Zudem soll der TO doch lernen und üben.



  • Wenn das sonst keiner macht, mache ich mal

    #include <ctype.h>
    
    char *strtoupper(char *p)
    {
      char *s=p;
      while( *s )
      {
        *s=toupper((unsigned char)*s);
        ++s;
      }
      return p;
    }
    

    Die strtolower-Variante wird wohl jeder selbst hinbekommen.



  • Wutz schrieb:

    char *strtoupper(char *p)}
    .....
    

    Es ging doch aber um strupr() aus string.h 😉

    Diese Funktionen muss man halt mal selber geschrieben haben, damit man den Umgang mit Zeichenketten in C lernt.



  • Zur Abgrenzung von solcherlei "Quasi"-Standardfunktionen ist es immer besser, dieselben Namen eben nicht zu benutzen und ein paar Buchstaben zusätzlich zu spendieren. Das spart Ärger nicht nur bei einer Portierung.



  • Lernen und üben ist ein gutes, starkes Argument.


Anmelden zum Antworten