Zeichenfolge in Großbuchstaben umwandeln (Funktion, Pointer,toupper)
-
Hallo Leute,
sitze schon sehr lange an einem Programm, mit dem ich nicht klar komme.
Meine Funktion char* gross(char* s) soll bewirken, dass mein Text in der main() in Großbuchstaben umgewandelt und ausgegeben wird.
Beim Debuggen sieht alles supper aus:
b return't meinen Text umgewandelt in Großbuchstaben,
jedoch taucht diese bei Ausgabe in der main() nicht auf!!
Bekomme bei jeder Ausführung eine andere Ausgebe (irgendwelche Zeichen).
Was mache ich falsch?
Bin für jede Art von Hilfe dankbar !!Folgender Code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>char* gross(char* s)
{char b[10] = {0};
int i = 0;
while(*s)
{b[i++] = toupper(*s++);
}
return b;
}int main()
{
char s[10] = "text";
printf("\n%s\n", gross(s));return 0;
}
-
return b;
gibt einen Zeiger zurück, so wie es ja auch die Signatur der Funktion vorschreibt. Aber worauf zeigt dieser Pointer? Er zeigt auf ein lokales Array, welches bei Beendigung der Funktion zerstört wird.
Mögliche Lösung wäre, direkt den übergebenen String zu ändern:
*s = toupper(*s++);
...
return s;
-
Danke für deine schnelle Antwort!
Diese Variante hatte ich auch schon durchgespielt,
die zwar fehlerfrei ist, aber bei der Ausfühhrung taucht eine Meldung von Windows auf, dass die .exe nicht funktioniert, debuggen geht auch nicht
-
Schreib das mal nacheinander:
*s = toupper(*s); s++;
Kannst du nicht nach dem Fehler debuggen oder kannst du gar nicht im Debugger starten?
-
Hat endlich geklappt!!
Mit
C/C++ Code:
*s = toupper(*s);
s++;konnte ich es zwar ausführen, die Ausgabe war jedoch leer.
Irgendwie musste der Zeiger wieder auf Anfang gesetzt werden.Deswegen habe ich noch einen zweiten Zeiger definiert, der vor der Umwandlung auf die erste Addresse meines Strings zeigt.
Nach der Umwandlung, habe ich den Zeiger von s wieder auf Anfang gesetzt mit Hilfe des neuen Zeigers (so eine Art Backup).Hier der Code:
char* gross(char* s)
{char* p;
p = s;
while(*s)
{*s = toupper(*s);
s++;
}
s = p;
return s;
}Danke für eure Hilfe!!
-
Ist zwar nicht ANSI-konform strupr aus string.h
-
Was heisst das?
Sorry, kenn mich da nicht so gut aus, bin Elektrotechniker, kein InformatikerDie Bibliothek string.h, kann ich auch auslassen. Hatte sie vorher nur eingefügt, als ich es mit strncpy propiert hatte.
Wenn du das meinst
-
raymon90 schrieb:
Nach der Umwandlung, habe ich den Zeiger von s wieder auf Anfang gesetzt mit Hilfe des neuen Zeigers (so eine Art Backup).
Hier der Code:
s = p;
return s;Jo, sorry, hab ich nicht bedacht. Statt wie oben kannst Du aber auch einfach:
return p;
machen.
@DirkB:
Wieso geht (anscheinend):b[i++] = toupper(*s++);
aber statt:
*s = toupper(*s++);
ist:
*s = toupper(*s); ++s;
erforderlich?
-
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önnenDü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.htmlSpeziell 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
-
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()
ausstring.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.