Funktion um Kleinbuchstaben in Strings in Großbuchstaben umzuwandeln



  • Kann mir jemand bei der Erklärung dieser Funktion helfen. Als Parameter soll ein string übergeben werden, dieser wird dann zum Schluss in Großbuchstaben returned. So den anfang versteh ich ja, aber dann:

    1. Warum ist der Parameter eine konstante Referenz? Das würde doch auch mit einer nich konstanten gehen, sodass man einfach gleich alles mit der Referenz macht und man müsste somit doch auch keine Hilfsvariable "string s" einführen und bräuchte auch kein return mehr???

    2. Was ist size_t?? Es schaut so aus als wäre das ein Datentyp? Aber was es genau ist weiß ich nicht, kann mir das jemand erklären?

    3. Was ist s.size()??? Ist das eine String Funktion wie strlen(..) bei char C-String. Wenn nicht bitte auch erklären.

    4. Was soll genau das string::iterator??? Das blick ich ja mal gar nicht. Ist das auch ein Typ?? schaut so aus aber so genau weiß ich das nicht. Dass bitte auch unbedingt erklären, und dann noch was die Funktion begin() genau bewirkt.

    5. Mh und das ab der while Schleife versteh ich auch nicht so ganz. In meinem C++ Buch habe ich gelernt: Solange while(...) <-- diese Anweisung == TRUE dann läuft die Schleife. Wenn die Anweisung aber == FALSE dann hört die Schleife auf. Aber die Anweisung hier (length--) mit der kann ich so gar nichts anfangen.

    6. Und woher kommt nun bitte der Zeiger\Dereferenzierungoperator *??? Das hat wohl wieder irgend einen Zusammenhang mit string::iterator aber os genau weiß ich das nicht. Okay und toupper is halt eine Funktion die den entsprechenden Großbuchstaben zurückgibt, wenn das übergebene Zeichen ein Kleinbuchstabe ist, das versteh ich mal noch.

    Dankeschön schon mal im Voraus.

    string toUpperString(const string &org)
    {
        string s=org;
        size_t length=s.size();
        string::iterator iter=s.begin();
        while(length--)
        {
            *iter=toupper(*iter);
            ++iter;
        }
        return(s);
    }
    

    PS: Entschuldigt für die für euch vll. dummen Fragen, ich will hier niemand im Forum damit stressen aber vll. gibts doch den ein oder anderen der mir meine Fragen beantwortet. Ich programmiere leider noch nicht so lange C++.



  • 1. dass die übergabe eine konstante Referenz ist scheint mir auch blödsinn, das sollte am besten direkt by value übergeben werden finde ich. Aber nicht einfach als non const referenz, weil man dann ja den ursprünglichen string ändert, was diese Funtkion nicht beabsichtigt.

    2. size_t ist der Datentyp für grössen... size halt.

    3. jupp, genau das is es. es ist ne methode der string Klasse, genauer gesagt.

    4. Ja ein iterator ist auch eine Art Typ. Ich würde dir mal anraten danach zu google, resp. auf www.BruceEckels.org (ich hoffe das ist die richtige Adresse gibts auch nen Part der sich damit befasst. Ein Iterator ist soweit ich weiss grob gesagt etwas wie ein index, aber aber eben nicht aus den Grenzen springen kann. Dient zum durchlaufen von containern.

    5. 0 steht für false und alle andern Zahlen für true. Sobald length-- also 0 zurückliefert (also wenn die Länge 0 WAR, da der postfix operator genutzt wird) unterbricht die whileschleife

    diese Funtkion konvertiert btw einen ganzen String in Grossbuchstaben, nicht nur einzelne Buchstaben.

    Bin selbst noch ANfänger, ich hoffe aber das ist soweit richtig.



  • Stromberg schrieb:

    1. Warum ist der Parameter eine konstante Referenz?

    Hast recht, ist total unnötig (und sogar unschön).

    Aber:

    Das würde doch auch mit einer nich konstanten gehen, sodass man einfach gleich alles mit der Referenz macht und man müsste somit doch auch keine Hilfsvariable "string s" einführen und bräuchte auch kein return mehr???

    Na, vielleicht will man ja, dass der Originalstring unberührt bleibt und stattdessen eine Kopie erstellt wird, die manipuliert und zurückgegeben wird. Aber auch in diesem Fall würde man keine const-Referenz übergeben.

    2. Was ist size_t??

    std::size_t ist ein vorzeichenloser Ganzzahltyp, der für Größen- und Positions- (Index-) angaben in Containern gedacht ist.

    3. Was ist s.size()???]

    Rat mal. Für sowas gibt es Dokumentationen, z.B. http://cppreference.com/

    4. Was soll genau das string::iterator??? Das blick ich ja mal gar nicht.

    Hmm. Ja, das ist auch ein Typ. Tip: Leg Dir ein C++-Buch zu. Ich behaupte, dass man C++ ohne Buch nicht lernen kann. Konzepte wie Iteratoren kann man in einem Forumposting nicht besonders gut erklären.

    5. Mh und das ab der while Schleife versteh ich auch nicht so ganz. In meinem C++ Buch habe ich gelernt: Solange while(...) <-- diese Anweisung == TRUE dann läuft die Schleife. Wenn die Anweisung aber == FALSE dann hört die Schleife auf. Aber die Anweisung hier (length--) mit der kann ich so gar nichts anfangen.

    Na, solange 'length--' > 0 ist, wird die Schleife ausgeführt. D.h. in jedem Schritt wird length verringert, bis es 0 ist. Hier wäre eine 'for'-Schleife syntaktisch besser geeignet als eine 'while'-Schleife.

    EDIT: Oh, Du hast ein C++-Buch. Gut ... da sollte auch irgendwo der Iterator erklärt werden.

    6. Und woher kommt nun bitte der Zeiger\Dereferenzierungoperator *??? Das hat wohl wieder irgend einen Zusammenhang mit string::iterator aber os genau weiß ich das nicht.

    Na ja, 'string::iterator' ist ein Typ, der gewissermaßen so tut, als sei er ein Zeiger auf einen char. Ist ein wenig komplizierter aber im Prinzip läuft's darauf hinaus. D.h. mit einem Iterator kann man all das tun, was man mit einem Zeiger so tun kann.



  • 1. Das ist eine Designentscheidung. Es ist nicht falsch. Wenn jemand meint, er will nicht den übergebenen Parameter ändern, sondern das geänderte lieber returnen... tja, dann ist das seine Entscheidung. Er nutzt halt eine Möglichkeit, die ihm die Sprache anbietet. Du kannst natürlich auch const weglassen und direkt am übergebenen Parameter rumwurschteln. Wäre auch nicht falsch.

    2. size_t ist ein Typ, richtig. Es ist der größt mögliche Typ. Man sollte meinen, das z.B. long groß genug ist, ist es aber nicht. long kann laut Standard genauso groß sein, wie char. Ist es meistens nicht, kann aber. Also gibt es size_t, welches auf jeden Fall das größt mögliche ist. Unter MSVC ist z.B. long selbst auf einem 64bit-System nur 32bit groß. Aber size_t ist dann 64bit.

    3. string::size() gibt die Stringlänge (also Anzahl Zeichen) zurück.

    4. iteratoren haben die Operatoren überladen, damit man sie wie Zeiger behandeln kann. *iter dereferenziert den Iterator. Also kriegst du den Inhalt auf den iter zeigt zurück.



  • Also ist size_t jetzt ein Typ für Ganzahlen??? Ganz große Ganzzahlen? Oder was speichert man in diesem? Und warum wird genau size_t dazu verwendet um die Anzahl der Buchstaben zu speichern??? Das müsste ja int locker reichen. Int geht doch bis 4294967295(unsigned). Und wer hat bitte eine string Variable die mehr Buchstaben beinhaltet als 4294967295?? Oder habe ich jetzt irgendwas falsch verstanden?
    Äh und noch kurze Zwischenfrage: Also wenn ich sizeof(int) mache und sizeof(long) dann sind bei mir beide 4Byte groß. Also ist es doch ganz egal ob ich int oder long verwende?
    Dankeschön schon mal im Voraus.

    ANHANG:
    In meinem Buch steht nichts über Iterator drin, nur Iteration und das is ja Schleifendurchlauf (auch nicht im Verzeichnis etc. (blödes Buch 🙂 ).
    Geht irgend wie nicht ---> www.BruceEckels.org. Vll. hat ja jemnad von euch noch einen guten Link für mich zu dem Thema. So ich werd jetzt dann aber auch mal selber googeln.



  • Die seite ist www.BruceEckel.com entschuldige, hatte da was falsch in Erinnerung.

    Ein int ist eben nicht gleich eine Grössenangabe. wenn ich 4 sage weisst du ja auch nicht ob oich 4cm, m, kubikmeter, liter oder was auch immer meine. Da fehlt halt die einheit. So stelle ich mir auch size_t vor: die Einheit für Vector, Array usw. grössen im pc.



  • Nein, ich hab es doch schon gesagt. Lese bitte meinen Beitrag nochmal durch.

    int ist bei dir zufällig 32 bit groß. Und was hab ich gesagt? Es muß nicht so sein! int kann auch so groß sein wie ein char!!!!!!!!!!!!! ⚠ ⚠ ⚠ Und willst du dann in einem String höchstens 255 Zeichen speichern können? 🙄

    Die Regel heißt:

    long >= int >= short >= bool >= char

    So, selbst wenn size() ein long zurück gibt, kann long nur 8 bit groß sein. Zufällig hat dein Compiler bei int aber 32 bit. Und? Was ist wenn du einen anderen Compiler nimmst? Nichts mit garantierten 32 bit.

    Aber size_t ist definitiv die größt mögliche Bitzahl die ein System hergibt. Üblicherweise auf einem 32bit-System ist size_t 32 bit groß.

    Und zu mutmaßen, das jemand nicht mehr Zeichen braucht, als ein int hergibt, wäre somit dumm. Was machst du, wenn ein Compiler ein int als 8 bit definiert? Tolle Wurst! Deshalb gibts bei sowas size_t.



  • Mh also eine Definition könnte dann sein:
    size_z ist der größte vorzeichenloser ganzzahl Variablentyp auf dem jeweiligen System mit dem jeweiligen Compiler.

    Oder so ähnlich?



  • Mh also eine Definition könnte dann sein:
    size_z ist der größte vorzeichenloser ganzzahl Variablentyp auf dem jeweiligen System mit dem jeweiligen Compiler.

    Oder so ähnlich?
    PS: Ich hab aber noch nie von einem int gehört das ein Byte groß ist und somit nur Zahlen bis 256 aufnehmen kann.



  • Stromberg schrieb:

    PS: Ich hab aber noch nie von einem int gehört das ein Byte groß ist und somit nur Zahlen bis 256 aufnehmen kann.

    Ich auch nicht aber C++ läuft ja nicht nur auf PCs sondern auf den perversesten Microcontrollern und was weiß ich nicht alles. Es muss halt so allgemein wie möglich gehalten werden, um eine optimale Portierbarkeit zu besitzen.



  • So ich habs jetzt so ungefähr geblickt hier ist nochmal eine schöne Version mit der for-Schleife, wie es Konrad Rudolph vorhin mal angesprochen hat. Die is find ich die beste.

    #include <iostream>
    #include <string>
    #include <cctype>
    using namespace std;
    
    string upperString(string &s);
    
    int main()
    {
        string a="Hans Werner Olm";
        cout << upperString(a) << endl;
        return 0;
    }
    string upperString(string &s)
    {
        string::iterator iter;
        for (iter=s.begin();iter!=s.end();iter++)
        {
            *iter=toupper(*iter);
        }
        return s;
    }
    


  • Ja, es mag sein das du das noch nie gehört hast. Und auf 32bit-CPUs ist es auch eher unwahrscheinlich. Aber nicht auszuschliessen und auf 16 bit oder 8 bit Systemen sogar mehr als wahrscheinlich.

    Schau mal das hier (die mir jetzt einfallen):

    MSVC Typen unter 32bit-Windows:
    int = 32 bit
    long = 32 bit
    wchar_t = 16 bit

    MSVC Typen unter 64bit-Windows:
    int = 32 bit
    long = 32 bit (hätte man eigentlich 64 bit vermuten können?)
    wchar_t = 16 bit

    GCC bzw. MinGW unter 32bit-Windows:
    wchar_t = 32 bit

    Mit den Größen der GCC-Datentypen kenne ich mich sonst weiter nicht aus. Vielleicht weiß jemand, wo man eine Tabelle dazu im Web findet?

    Aber man sieht, es ist nichts garantiert, selbst auf ein und dem selben System. Schon ein anderer Compiler kann Unterschiede machen.



  • Artchi schrieb:

    MSVC Typen unter 64bit-Windows:
    int = 32 bit
    long = 32 bit (hätte man eigentlich 64 bit vermuten können?)

    stimmt das?
    ich hätte ja schon bei 'int' 64 bits vermutet.
    long natürlich auch.



  • 🙄 Schau einfach in die MSDN, da gibts ne Auflistung aller Typen, die MSVC kennt. Für 64 Bit wurde dagegen __int64 eingeführt. Es gibt noch long long, ich schätze mal, es ist ein typedef auf __int64 (kann ich aber aus der MSDN nicht herauslesen).

    http://msdn2.microsoft.com/en-us/library/cc953fe1.aspx

    Unter einem 64 Bit GCC kann natürlich int schon 64 Bit sein. Weiß ich aber nicht.



  • Artchi schrieb:

    Unter einem 64 Bit GCC kann natürlich int schon 64 Bit sein. Weiß ich aber nicht.

    auf der kiste da ist sizeof(int) 4 und sizeof(long) 8
    (gcc 4.1.2)



  • ten schrieb:

    Artchi schrieb:

    MSVC Typen unter 64bit-Windows:
    int = 32 bit
    long = 32 bit (hätte man eigentlich 64 bit vermuten können?)

    stimmt das?
    ich hätte ja schon bei 'int' 64 bits vermutet.
    long natürlich auch.

    Nene ... allerdings sollte ptrdiff_t 64 Bit haben.



  • Konrad Rudolph schrieb:

    ten schrieb:

    Artchi schrieb:

    MSVC Typen unter 64bit-Windows:
    int = 32 bit
    long = 32 bit (hätte man eigentlich 64 bit vermuten können?)

    stimmt das?
    ich hätte ja schon bei 'int' 64 bits vermutet.
    long natürlich auch.

    Nene ... allerdings sollte ptrdiff_t 64 Bit haben.

    wie? nö, die 64 bits eines '64 bitters' beziehen sich ja auf die anzahl der datenleitungen, registerbreite etc, nicht wie breit der adressbus ist...



  • Hähä, ja, die 64 bit können sich auf alles unterschiedliche beziehen. Bei x86-CPUs auf die Adressraum-Größe: halt 64bit Adressen. Damit kann z.B. ein Athlon64 endlich mehr als 4 GB RAM ansprechen (machen aber die ganzen Mainstream-Mainboards nicht).

    Andere 64 Bit CPUs werden wohl nur 32 Bit Adressräume haben. Die damaligen ARM-Prozessoren (ARM 2 und ARM 3) waren echte 32 Bit CPUs, aber der Adressraum war nur 26 Bit groß (das eine 32 Bit Register für den Programmcounter mußte sich ein paar Bits für andere Flags teilen).



  • Ah ja wenn ich das jetzt alles nochmal zusammenfass hab ich das so verstanden das es verschiedene Compiler gibt und es somit auch mal sein kann das auf einem int ein byte groß ist, obwohl das system z.B. ein 64-bit system ist. Ah ja okay, darum gibts size_t das is n Typ der immer der größtmöglichen vorzeichenlose Ganzzahlentyp auf dem jeweiligen system und jeweiligen compiler ist.
    Hm dann stellt sich mir Frage 1: Wieviele Compiler gibt es eigentlich????
    Und dann stellt sich mir noch 2: Ich hab schon öfters was von einer ISO\ANSI Norm der Compiler gehört. Aber das kann doch dann bitte nichts mehr mit einer Norm zu tun haben wenn ein int auf einem 32bit system ein byte groß ist. Oder??? Okay ich würde es verstehen wenn auf einem ganz alten Pc der Compiler die Typen einfach automatisch anpasst und somit alle ein Byte z.B. haben.....!
    Kann mr jemand dir Fragen beantworten???
    Dankeschön schon mal im Voraus.


  • Mod

    Konrad Rudolph schrieb:

    [std::size_t ist ein vorzeichenloser Ganzzahltyp, der für Größen- und Positions- (Index-) angaben in Containern gedacht ist.

    Nein. Dafür ist <container_typ>::size_type bzw difference_type zuständig. Allerdings gibt es eine natürliche Beziehung zwischen beiden Typen (auf Systemen mit flachen Adressräumen).

    Artchi schrieb:

    2. size_t ist ein Typ, richtig. Es ist der größt mögliche Typ.

    Nein.

    Artchi schrieb:

    int ist bei dir zufällig 32 bit groß. Und was hab ich gesagt? Es muß nicht so sein! int kann auch so groß sein wie ein char!!!!!!!!!!!!! ⚠ ⚠ ⚠ Und willst du dann in einem String höchstens 255 Zeichen speichern können?

    Abschnitt 5.2.4.2.1 von C90 enthält Grenzwerte für die Makros in <limits.h>, diese sind damit auch für C++ (vermittelt durch C2/4 in C++98 bzw C++03) gültig. Damit ergeben sich folgende Mindestgrößen in bit:
    char: 8
    short: 16
    int: 16
    long: 32

    Natürlich kann z.B. sizeof(long)==1 zutreffen, dann hat aber das char auf diesem System wenigstens 32bit.

    size_t ist ein vorzeichenloser integraler Typ, dessen Größe durch die Implementation vorgegeben ist (6.3.3.4 in C90 bzw. 6.5.3.4/4 in C99). Es ist also nicht notwendig der größte existierende Typ auf dieser Platform, möglicherweise muss er nicht einmal mit einem der 4 obigen Grundtypen übereinstimmen. Die Bedeutung dieses Typs entsteht dadurch, dass size_t der Ergebnistyp des sizeof Operators ist. ptrdiff_t ist übrigens das vorzeichenbehaftete Equivalent zu size_t (also gleiche Größe). Damit ist auch leicht ein klassisches Beispiel für kleine size_t gegeben:
    Auf einem 16bit DOS System sind Segmente (=sequences of contiguous bytes im Sinne von 1.7/1) maximal 64K groß. Folglich muss size_t hier nicht größer als 16bit sein, ein long dagegen immer noch wenigstens 32bit.

    Die Größe von wchar_t und bool ist nicht vorgegeben. Allerdings muss wchar_t mit einem der (standardisierten) integeralen Typen hinsichtlich Größe und Repräsentation übereinstimmen.

    Um es deutlich zu sagen: es gibt keinen portablen integralen Typ, der auf allen Systemen garantiert der Größte ist.


Anmelden zum Antworten