Forum: PC-Programmierung C++: tolower() Funktion Frage


von tsepepe (Gast)


Lesenswert?

Hallo zusammen, ich habe hier einen C++ Codeausschnitt, kann mir jemand 
erklären was hier passiert? Das ganze macht für mich auf den ersten 
Blick keinen Sinn:
1
void tolower(string& s) // put s into lower case
2
{
3
   for (char& x : s) x = tolower(x);
4
}

Es wird der string s als Referenz übergeben und alle Zeichen des Strings 
sollen in Kleinbuchstaben umgewandelt werden. Wo passiert denn das? Ich 
sehe nicht dass irgendwas an s gemacht wird.
Und dann frage ich mich warum x eine Referenz ist, das macht in diesem 
Beispiel für mich irgendwie keinen Sinn.

von Dr. Sommer (Gast)


Lesenswert?

tsepepe schrieb:
> Wo passiert denn das? Ich
> sehe nicht dass irgendwas an s gemacht wird.

Da steht "char&", dadurch ist "x" eine Referenz auf das Zeichen in s. 
Das x wird geändert, d.h. das referenzierte Zeichen in s.

von Test (Gast)


Lesenswert?

Der String s wird durchlaufen und jedes einzelne Zeichen des Strings 
wird mit tolower(x) durch einen Kleinbuchstaben ersetzt. Der String s 
wird in diesem Fall überschrieben, deswegen ist x eine Referenz.

von Theor (Gast)


Lesenswert?

@ Dr. Sommer

Magst Du bitte einen Link posten, wo man das mal nachlesen kann?
Ist ':' ein nativer Operator oder einer der String-Klasse?
Oder was ganz Anderes?

(Ich habe selber gesucht,aber nichts dazu gefunden. Vermutlich weil ich 
an den falschen Stellen gesucht habe. z.B.: 
http://www.cplusplus.com/reference/string/string/ 
https://www.w3schools.com/cpp/cpp_operators.asp).

von Vincent H. (vinci)


Lesenswert?

Theor schrieb:
> @ Dr. Sommer
>
> Magst Du bitte einen Link posten, wo man das mal nachlesen kann?
> Ist ':' ein nativer Operator oder einer der String-Klasse?
> Oder was ganz Anderes?
>
> (Ich habe selber gesucht,aber nichts dazu gefunden. Vermutlich weil ich
> an den falschen Stellen gesucht habe. z.B.:
> http://www.cplusplus.com/reference/string/string/
> https://www.w3schools.com/cpp/cpp_operators.asp).

https://en.cppreference.com/w/cpp/language/range-for

von Dr. Sommer (Gast)


Lesenswert?

Theor schrieb:
> Magst Du bitte einen Link posten, wo man das mal nachlesen kann?

https://en.cppreference.com/w/cpp/language/range-for

Theor schrieb:
> Ist ':' ein nativer Operator oder einer der String-Klasse?

Das ist kein Operator, und kann auch nicht überladen werden. Das ist ein 
fixes Sprachkonstrukt, welches mit allen Klassen funktioniert, für 
welche die Funktionen begin und end definiert sind, d.h. mit allen 
Containern & Arrays inklusive std::string.

von Theor (Gast)


Lesenswert?

@ Vincent H. (vinci)
@ Dr. Sommer (Gast)

Danke sehr. :-)

von tsepepe (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Da steht "char&", dadurch ist "x" eine Referenz auf das Zeichen in s.
> Das x wird geändert, d.h. das referenzierte Zeichen in s.

Danke, sehr einfach aber klar erklärt, habe es jetzt verstanden.

Die for-schleife hier ist ja die Kurzversion die es seit C++11/C++14 
gibt, wie würde der code aussehen wenn man die normale for-schleife von 
C++98 nehmen würde? Es handelt sich hier ja um einen string der 
verarbeitet wird, bei einem vector ist mir das schon klar .

von mh (Gast)


Lesenswert?

tsepepe schrieb:
> Es handelt sich hier ja um einen string der
> verarbeitet wird, bei einem vector ist mir das schon klar .

Dann schreib es für einen std::vector hin und guck, ob es die benötigten 
Funktionen auch für std::string gibt.

von tsepepe (Gast)


Lesenswert?

mh schrieb:
> Dann schreib es für einen std::vector hin und guck, ob es die benötigten
> Funktionen auch für std::string gibt.

Ich rede von der Elementweisen Verarbeitung von Vektoren, das hat doch 
mit Zeichenweiser Verarbeitung von Strings nichts zu tun.

von Yalu X. (yalu) (Moderator)


Lesenswert?

tsepepe schrieb:
> Ich rede von der Elementweisen Verarbeitung von Vektoren, das hat doch
> mit Zeichenweiser Verarbeitung von Strings nichts zu tun.

Wieso nicht? Die Zeichen sind nichts anderes als die Elemente des
Strings.

von Dr. Sommer (Gast)


Lesenswert?

tsepepe schrieb:
> wie würde der code aussehen wenn man die normale for-schleife von
> C++98 nehmen würde?
1
void tolower(std::string& s) {
2
  for (std::string::iterator i = s.begin(); i != s.end(); ++i) {
3
    *i = std::tolower(*i);
4
  }
5
}

Ziemlich genau das wird auch aus der range-for-loop.

von tsepepe (Gast)


Lesenswert?

Dr. Sommer schrieb:
> void tolower(std::string& s) {
>   for (std::string::iterator i = s.begin(); i != s.end(); ++i) {
>     *i = std::tolower(*i);
>   }
> }
>
> Ziemlich genau das wird auch aus der range-for-loop.

Klasse vielen Dank! Ich glaub ich nehm bei dir nen C++ Aufbaukurs :-p

von tsepepe (Gast)


Lesenswert?

Dr. Sommer schrieb:
> void tolower(std::string& s) {
>   for (std::string::iterator i = s.begin(); i != s.end(); ++i) {
>     *i = std::tolower(*i);
>   }
> }
>
> Ziemlich genau das wird auch aus der range-for-loop.

Klasse vielen Dank! Ich glaub ich nehm bei dir nen C++ Aufbaukurs xD

von Dr. Sommer (Gast)


Lesenswert?

tsepepe schrieb:
> Ich glaub ich nehm bei dir nen C++ Aufbaukurs xD

Gönn dir! C++ Seminare geben ist kein schlechtes Geschäftsmodell glaube 
ich :-)

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> tsepepe schrieb:
>> Ich rede von der Elementweisen Verarbeitung von Vektoren, das hat doch
>> mit Zeichenweiser Verarbeitung von Strings nichts zu tun.
>
> Wieso nicht? Die Zeichen sind nichts anderes als die Elemente des
> Strings.

Allerdings. Wenn man statt eines std::string einen std::vector<char> 
genommen hätte, würde der Code ansonsten exakt gleich aussehen.

tsepepe schrieb:
> Die for-schleife hier ist ja die Kurzversion die es seit C++11/C++14
> gibt,

Ja, nennt sich "range-based for".

Dr. Sommer schrieb:
> void tolower(std::string& s) {
>   for (std::string::iterator i = s.begin(); i != s.end(); ++i) {
>     *i = std::tolower(*i);
>   }
> }
> Ziemlich genau das wird auch aus der range-for-loop.

Der einzige Unterschied ist, dass das range-based for nicht direkt 
s.begin() aufruft, sondern begin(s).

von Dr. Sommer (Gast)


Lesenswert?

Rolf M. schrieb:
> Der einzige Unterschied ist, dass das range-based for nicht direkt
> s.begin() aufruft, sondern begin(s).

Jo, das gibt's aber in C++03 nicht :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.