[C++] Convert lowercase zu uppercase cctype.h

TK-Shockwave

Lt. Commander
Registriert
März 2003
Beiträge
1.309
Hallo,

ich hab das Problem wenn ich dieses Programm ausführe, gehts nach den ersten Satz net weiter. also das erste cout.

Dann werden 50% CPU Ressouces verballert aber nichts passiert der Code sollte korrekt sein, ich find den Fehler nicht.

Code:
#include <iostream>
#include <cctype>

using namespace std;

void convertToUppercase( char * ); // prototyp for islower and toupper

int main() {
	
	char phrase[] = "characters and $32.9";
	
	cout << "The phrase before conversion is: " << phrase;
	convertToUppercase( phrase );
	cout << "\nThe phrase after conversion is: " << phrase << endl;
	
	system("PAUSE"); // required to stay in console while windows close it after execution
	return 0; // indicates normal program termination
	
}
// convert string uppercase latters
void convertToUppercase( char *sPtr ) { 
	
	while ( *sPtr != '\0' ) {	// current character is not '\0'
		if ( islower( *sPtr ) ) { // if character is lowercase
		
			*sPtr = toupper( *sPtr ); // convert to uppercase
		
			++sPtr; // go to next character in string
		}
	}
}

Irgend welche Ideen wären super..benutze GCC3.4.4 und 4.0.1 und überall das selbe :-(
 
die if-abfrage in convertToUppercase() ist so nicht ganz richtig.
Wenn der der char nicht lower ist geht die schleife im string nicht weiter.

du könntest das durch
( *sPtr != '\0' )?*sPtr = toupper( *sPtr );

oder
while ( *sPtr != '\0' ) {
if( islower( *sPtr ) ){
sPtr = toupper( *sPtr );
}
++sPtr;
}

lösen
 
Zuletzt bearbeitet:
Hi,

das islower in deinem Programm ist überflüssig. toupper konviertiert nur Zeichen, die auch lower sind. Außerdem enthält es einen kritischen, eher unbekannten aber oft gemachten Fehler.

Die Signatur von toupper sieht so aus: int toupper( int c);
Grund dafür ist, dass auch noch das EOF-Zeichen übergeben werden kann, das keine Kodierung im ASCII-Zeichensatz hat, es ist also nicht als char darstellbar und wird soweit ich weiß als -1 kodiert. Das setzt aber voraus, dass das übergebene Zeichen ein unsigned char ist (damit es keine Kollisionen für -1 gibt). Und das ist auch der Fehler in deinem Programm - du übergibst char. Für char ist nicht festgelegt, ob es signed oder unsigned ist (auch wenn es letztendlich eines von beiden ist). Wenn Du eine dieser Funktionen mit einem signed char aufrust und das Zeichen >127 (also -128 - -1) ist, so ergibt das undefiniertes Verhalten. Da der Parameter wie schon gesagt int ist, gibt es auch keinen impliziten cast nach unsigned char.

Hier auch ein Zitat aus einer UNIX-Manpage von toupper / tolower:
If c is not an unsigned char value, or EOF, the behaviour of these functions is undefined.
Das kann sich dann z.B. in einer Debug-Assertion äußern, die absolut nicht nachzuvollziehen ist, wenn man den Fehler nicht kennt.

Um das ganze auf den Punkt zu bringen: So müsste es aussehen:
Code:
void convertToUppercase( char *sPtr ) { 
	while ( *sPtr != 0 ) {	// current character is not '\0'
		*sPtr = toupper( static_cast<unsigned char>(*sPtr)); // convert to uppercase
		++sPtr; // go to next character in string
	}
}

Ich würde dir übrigens empfehlen, immer auch einen optionalen Längen-Parameter mitzugeben, wenn man mit Funktionen arbeitet, die auf nullterminierten Strings arbeiten. Ganz einfach, um Buffer-Overflow-Fehlern vorzubeugen. Und wenn es nicht gerade ein Beispiel für die Schule ist, würde ich Dir auch zu std::string raten, um sich das ganze, potenziell unsichere Pointer-Gefrickel zu sparen.
 
dazu sollte man natürlich noch sagen das das ganze c und nicht c++ ist, nicht das einige unserer anfänger gleich wieder einen falschen eindruck von c++ bekommen ;).
 
@Siberian..Husky
Es handelt sich in dem Beispiel aber um ein C++ Programm (nur die Funktionen stammen aus der C-Bibliothek). Und das Verhalten von toupper/tolower (+ eigentliche alle anderen Funktionen in der Sparte (is_alnum, etc)) ist in C wie in C++ in dem Kontext undefiniert. Man muss in jedem Fall vorher nach unsigned char casten.

Wenn Du sowas machst
Code:
std::string s = "böser String mit Zeichen >127";
transform( s.begin(), s.end(), s.begin(), toupper);
kann das ganz genauso undefiniert sein.
 
Alles Schön und gut aber nur einer hatte die korrekte Lösung!
Ich habe ++sPtr noch im If-Block gehabt was den Fehler verursachte..nach Debuggen hat sich der Fehler auf gefunden..

Danke euch
 
TK-Shockwave schrieb:
Alles Schön und gut aber nur einer hatte die korrekte Lösung!
Ich habe ++sPtr noch im If-Block gehabt was den Fehler verursachte..nach Debuggen hat sich der Fehler auf gefunden..

Danke euch
Das es schon gelöst war, war ja offensichtlich ;) Deshalb auch nix weiter dazu. Außerdem ist der if-Block wie schon gesagt überflüssig ;)

Gruß
 
Zurück
Oben