Großschreibung für mehrere Variablen?
-
Hallo,
ich hoffe es kann mir jemand helfen.Hab zur Großschreibung eines Strings folgenden Code benutzt, es wird aber eine andere Variable (string du) auch großgeschrieben wird, obwohl ich das nicht will.
#include <iostream> #include <string> using namespace std; int main() { string ich; cin >> ich; string du = ich; strupr( (char*)ich.c_str() ); cout << endl << "Ich: " << ich; cout << endl << "Du: " << du; return 0; }Weiß nicht wieso, aber der string du wird auch automatisch GROSS-geschrieben. Ich will den string du aber wie eingegeben belassen, deswegen schreibe ich ja auch "string du = ich;".
Vielen Dank.
r.
-
Hallo
du hast da durch Vermischung von C und C++ undefiniertes Verhalten verursacht, wodurch es zu dieser Ausgabe kommt. Und zwar hast du zwei std::string. Durch das zuwesien von ich auf du wird durch das intelligente Kopierverhalten deiner Implementation intern nur ein Pointer von dem internen char-Pointer kopiert, nicht aber der Inhalt ansich.
Da du aber dann einen C-Style Cast einsetzt, um den eigentlich konstanten C-String zu ändern, wird dadurch der Inhalt beider string-Instanzen geändert.Benutzte deshalb in C++ immer die C++ casts. Damit wird dir gesagt das deine Umdandlung nicht erlaubt ist (es sei denn du setzt const-cast ein).
Die Lösung ist, das du dich nach toupper umschaust.
bis bald
akari
-
composed04 schrieb:
strupr( (char*)ich.c_str() );
Undefiniertes Verhalten. c_str gibt nicht umsonst einen Zeiger auf const charT zurück. Was lässt dich eigentlich glauben, du darfst hier einfach das const wegcasten?
The program shall not alter any of the values stored in the array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of the class basic_string that designates the same object as this.
Generell sind C-String Funktionen und std::string keine gute Mischung.
-
Umwandlung in Großbuchstaben:
std::transform(ich.begin(), ich.end(), ich.begin(), _totupper);
-
pZy schrieb:
Umwandlung in Großbuchstaben:
std::transform(ich.begin(), ich.end(), ich.begin(), _totupper);ach was
std::transform(ich.begin(), ich.end(), ich.begin(), std::bind2nd(std::toupper<char>, std::locale()) );
-
use_facet<ctype<string::value_type> >(locale()).toupper(ich.begin(), ich.end());
-
Danke,
eure Antworten waren sehr hilfreich.r.
-
Braunstein schrieb:
use_facet<ctype<string::value_type> >(locale()).toupper(ich.begin(), ich.end());schön wärs. dieser toupper-overload arbeitet mit pointern und nicht iteratoren. damit wird das ganze unportabel.
-
composed04 schrieb:
Hab zur Großschreibung eines Strings folgenden Code benutzt, es wird aber eine andere Variable (string du) auch großgeschrieben wird, obwohl ich das nicht will.
#include <iostream> #include <string> using namespace std; int main() { string ich; cin >> ich; string du = ich; strupr( (char*)ich.c_str() ); cout << endl << "Ich: " << ich; cout << endl << "Du: " << du; return 0; }r.
@compose04 mit welchem Compiler hast du das beschriebene Fehlverhalten erzeugt?
Ich war über diverse Aussagen hier etwas kritisch und hab den Code mit VC++ 2005 und gcc-3.4.4 getestet. Beide Compiler produzieren nicht den Fehler, den Du beschreibst!
VS2005 warning C4996: 'strupr' wurde als veraltet deklariert
Ausgabe jeweils:
Ich: ICH
Du: ich
-
Es ist implementierungsabhängig, deshalb hast du ein anderes Ergebnis. Normalerweise kenne ich es so, das std::string ein Copy-on-Write (bzw. Copy-on-Modify) Verhalten hat (wie es beim ersten Posting der Fall ist). Da dieses Speicherschonender ist. Aber wenn der Implementierer von std::string es anders sieht, kann es das Verhalten vom VC++8.0 sein.
-
Hallo
@Helmut S. : es kann schon sein, das bei deinem Compiler bzw. bei deiner STL-Implementation der Wert des string wirklich kopiert wird, und nicht nur ein Zeiger übernommen wird. Das spielt aber keine Rolle, denn durch den cast wird der Standard verletzt und damit undefiniertes Verhalten erzeugt. Davon ist dringenst abzuraten. Denn auf andern Implementation kann alles mögliche passieren.
bis bald
akari
-
es gibt auch andere möglichkeiten. es könnte sich z.b. um eine string-implementation handeln, die den string selbst nicht als array speichert und das ergebnis von c_str erst beim aufruf erzeugt (dann gibt es irgendwo wohl auch noch einen garbage collector). auch in diesem falle würde das verändern von c_str nicht das gewünschte ergebnis haben.
-
*falscher Thread*
-
hab den Borland C++ Compiler 5.5 benutzt.