C/C++ automatisch Großbuchstaben
-
Einem if kannst du viel komplexere Ausdrücke zum Auswerten geben. Den von mir oben geschriebenen Code kannst du nicht in der Kürze mit einem switch nachbauen.
-
DarthZiu: Eine map ist in diesem Fall ja mal eindeutig Overhead. Dann kannst du auch gleich ne Zeichenkette nehmen:
char ein[] = "ABC"; char aus[] = "DZX";
-
hmm... also muss ich doch beide arten eingeben und ich dachte man kann das so machen wie bei der tastatur, dass man nur großbuchstaben eingibt (mit der dauer umschalt taste)
-
gibs bei der einen variante nicht einige probleme später, wenn man so weit ist
if(zeichen >= 'a' && zeichen <= 'Z' ) zeichen = 'Z' - (zeichen -'a');
if(zeichen)>= 'z' && zeichen <= 'A' ) zeichen = 'A' - (zeichen -'z');oder ???
-
Was heißt denn, wenn man so weit ist? Mein Code Snippet ist vollständig, da brauchst du keine weiteren ifs einzufügen.
-
ich meine ja nur das ich schon so weit bin das ich das ganze abc hab hier der code ich weis nur nicht ob das so geht.
#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <iostream.h> main { char zeichen, zeichen2, wort; int i,x; printf ("Codierer\n"); //printf ("wieviele Buchstaben möchten sie codieren:"); // scanf ("%i", &x); printf ("Geben sie einen buchstaben ein:"); scanf ("%c", &zeichen); if(zeichen >= 'a' && zeichen <= 'Z'); if(zeichen >= 'b' && zeichen <= 'x'); if(zeichen >= 'c' && zeichen <= 'Y'); if(zeichen >= 'd' && zeichen <= 'W'); if(zeichen >= 'e' && zeichen <= 'V'); if(zeichen >= 'f' && zeichen <= 'U'); if(zeichen >= 'g' && zeichen <= 'T'); if(zeichen >= 'h' && zeichen <= 'S'); if(zeichen >= 'i' && zeichen <= 'R'); if(zeichen >= 'j' && zeichen <= 'Q'); if(zeichen >= 'k' && zeichen <= 'P'); if(zeichen >= 'l' && zeichen <= 'O'); if(zeichen >= 'm' && zeichen <= 'M'); if(zeichen >= 'n' && zeichen <= 'N'); if(zeichen >= 'o' && zeichen <= 'L'); if(zeichen >= 'p' && zeichen <= 'K'); if(zeichen >= 'q' && zeichen <= 'J'); if(zeichen >= 'r' && zeichen <= 'I'); if(zeichen >= 's' && zeichen <= 'H'); if(zeichen >= 't' && zeichen <= 'G'); if(zeichen >= 'u' && zeichen <= 'F'); if(zeichen >= 'v' && zeichen <= 'E'); if(zeichen >= 'w' && zeichen <= 'D'); if(zeichen >= 'x' && zeichen <= 'C'); if(zeichen >= 'y' && zeichen <= 'B'); if(zeichen >= 'z' && zeichen <= 'A'); if(zeichen2 = 'A' - (zeichen - 'z'); if(zeichen2 = 'B' - (zeichen - 'y'); if(zeichen2 = 'C' - (zeichen - 'x'); if(zeichen2 = 'D' - (zeichen - 'w'); if(zeichen2 = 'E' - (zeichen - 'v'); if(zeichen2 = 'F' - (zeichen - 'u'); if(zeichen2 = 'G' - (zeichen - 't'); if(zeichen2 = 'H' - (zeichen - 's'); if(zeichen2 = 'I' - (zeichen - 'r'); if(zeichen2 = 'J' - (zeichen - 'q'); if(zeichen2 = 'K' - (zeichen - 'p'); if(zeichen2 = 'L' - (zeichen - 'o'); if(zeichen2 = 'M' - (zeichen - 'n'); if(zeichen2 = 'N' - (zeichen - 'm'); if(zeichen2 = 'O' - (zeichen - 'l'); if(zeichen2 = 'P' - (zeichen - 'k'); if(zeichen2 = 'Q' - (zeichen - 'j'); if(zeichen2 = 'R' - (zeichen - 'i'); if(zeichen2 = 'S' - (zeichen - 'h'); if(zeichen2 = 'T' - (zeichen - 'g'); if(zeichen2 = 'U' - (zeichen - 'f'); if(zeichen2 = 'V' - (zeichen - 'e'); if(zeichen2 = 'W' - (zeichen - 'd'); if(zeichen2 = 'Y' - (zeichen - 'c'); if(zeichen2 = 'X' - (zeichen - 'b'); if(zeichen2 = 'Z' - (zeichen - 'a'); printf ("%c", zeichen); printf ("%c", zeichen2); getch(); }
-
Dir ist wohl immer noch nicht klar, was ich meine. Das hier ist ein vollständiges Programm, probiers aus:
#include <iostream> using namespace std; int main() { char zeichen; cin >> zeichen; if(zeichen >= 'A' && zeichen <= 'Z') zeichen = 'Z' - (zeichen - 'A'); else if(zeichen >= 'a' && zeichen <= 'z') zeichen = 'z' - (zeichen - 'a'); else { cout << "Die Eingabe ist nicht korrekt"; return -1; } cout << zeichen; return 0; }
-
@Vampir87: mit der Anzahl aufeinanderfolgender, sich bedenklich ähnelnder Codezeilen steigt die Wahrscheinlichkeit, daß du einen Designfehler begehst.
-
achso ich kenne mich ja noch nicht so aus mit c/c++ danke für den code
-
Michael E. schrieb:
Du kannst dir sogar den ganzen switch sparen und zum Beispiel sowas schreiben:
// dreht das Alphabet um if(zeichen >= 'A' && zeichen <= 'Z') zeichen = 'Z' - (zeichen - 'A'); if(zeichen >= 'a' && zeichen <= 'z') zeichen = 'z' - (zeichen - 'a');Hmmmm, portabel das ist aber nicht mehr. In ASCII klappt das natürlich, aber z.B. in EBCDIC nicht. Auch wenn Portabilität nicht jedesmal notwendig ist, würde ich mir das gar nicht angewöhnen....
wenn man sich ein case sparen möchte, bietet sich ein Array eher an....Entweder so, wie Du schon beschrieben hast mit ein/aus-Map:
char const ein[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char const aus[] = "DZXKFBDIKSJNMNKJVIJFHVNÖLA"; int findeEinPosition(char c) { static const len = strlen(ein); int pos = 0; while(pos < len) { if(ein[pos] == c) return pos; ++pos; } return -1; } int main(void) { std::string in_str = "Mein Teststring"; std::string out_str; std::string::iterator it = in_str.begin(); int pos; // string als Container durchgehen - kann man natürlich auch anders machen for(std::string::const_iterator end = in_str.end(); end != it; ++it) { if(0 > (pos = findeEinPosition(toupper(*it)))) return -1; // ungültiges Zeichen -> Fehler out_str.push_back(aus[pos]); } return 0; }Oder mit direktem Mapping (unkomfortabler, dafür schneller):
char cmap[256]; void initmap() { memset(cmap, 0xFF, sizeof(cmap)); cmap[static_cast<size_t>('A')] = 'D'; cmap[static_cast<size_t>('B')] = 'Z'; cmap[static_cast<size_t>('C')] = 'X'; cmap[static_cast<size_t>('D')] = 'K'; cmap[static_cast<size_t>('E')] = 'F'; cmap[static_cast<size_t>('F')] = 'B'; cmap[static_cast<size_t>('G')] = 'D'; cmap[static_cast<size_t>('H')] = 'I'; cmap[static_cast<size_t>('I')] = 'K'; cmap[static_cast<size_t>('J')] = 'S'; cmap[static_cast<size_t>('K')] = 'J'; cmap[static_cast<size_t>('L')] = 'N'; cmap[static_cast<size_t>('M')] = 'M'; cmap[static_cast<size_t>('N')] = 'N'; cmap[static_cast<size_t>('O')] = 'K'; cmap[static_cast<size_t>('P')] = 'J'; cmap[static_cast<size_t>('Q')] = 'V'; cmap[static_cast<size_t>('R')] = 'I'; cmap[static_cast<size_t>('S')] = 'J'; cmap[static_cast<size_t>('T')] = 'F'; cmap[static_cast<size_t>('U')] = 'H'; cmap[static_cast<size_t>('V')] = 'V'; cmap[static_cast<size_t>('W')] = 'N'; cmap[static_cast<size_t>('X')] = 'Ö'; cmap[static_cast<size_t>('Y')] = 'L'; cmap[static_cast<size_t>('Z')] = 'A'; } int main(void) { std::string in_str = "Mein Teststring"; std::string out_str; std::string::iterator it = in_str.begin(); int newc; initmap(); // string als Container durchgehen - kann man natürlich auch anders machen for(std::string::const_iterator end = in_str.end(); end != it; ++it) { if(0xFF == (newc = cmap[toupper(*it)])) return -1; // ungültiges Zeichen -> Fehler out_str.push_back(newc); } return 0; }BTW: Ist eigentlich C und nicht "++" (wenn man mal vom string absieht)...
Gruß,
Simon2.
-
danke für die Codes, nur bei den vielen Codes kommen wider neue fragen,
da ich noch nicht soweit bin in c/c++ wie z.B. was ist EBCDIC
oder was mich auch schon die ganze zeit durch den kopf geht für was steht bzw.
was ist std:: das steht nicht in meinem buch drin
-
Hi Vampir87,
EBCDIC ist ein "Zeichensatz" ... ASCII ein anderer. Einen Zeichensatz braucht eine Maschine (eher ein Betriebssystem, aber lassen wir mal die Haarspaltereien), um zu wissen, welches Zeichen sie ausgeben soll. Die Maschine "kennt ja nur Nullen und Einsen". Deswegen braucht man eine "Umsetzungstabelle", um zu einem bestimmten Wert (z.B. 0x41) den passenden Buchstaben (hier: 'A') auf der Konsole auszugeben.
Ebenso andersherum: Gibst Du über eine Konsole ein 'A' ein, bekommt die Maschine (und das Programm) den Wert 0x41 geliefert (und arbeitet mit dem).Windows- und Unix-Maschinen arbeiten oft mit ASCII, zOS-Geräte dagegen oftmals mit EBCDIC. Außerdem gibt es jeweils "Varianten" dieser Zeichensätze, z.B. brauchen wir deutsche Umlaute, wohingegen die Spanier ganz andere sprachspezifische Zeichen brauchen. ... da kann man sich mit unportablem Code leicht Feinde machen.

Vampir87 schrieb:
...für was steht bzw.
was ist std:: das steht nicht in meinem buch drin
Das ist ein Namespace. Da gibt's viel drüber zu lesen.
Ganz kurz: Damit man mit den ganzen Klassen-, Funktions-, Konstanzen-, ...-namen sich nicht in die Quere kommt, kann man sie in Namespaces organisieren. Da ist dann std::vector eine Klasse und boost::vector eine ganz andere.
Vereinfachen kann man den Zugriff per "using" (nachlesen !), aber damit sollte mn vorsichtig sein, weil man sich damit wieder in Mehrdeutigkeiten verheddern kann.Gruß,
Simon2.
-
@Michael E.
Was soll eigentlich das
if(zeichen >= 'A' && zeichen <= 'Z') zeichen = 'Z' - (zeichen - 'A');bedeuten?
Das wandelt doch zeichen in 'Z'+'A' - zeichen um

-
danke für die erklärung Simon2, danke noch mal für die Codes, die wahren alle sehr hilfreich.
-
Gern geschehen !
Dafür ist das Forum ja da.

Gruß,
Simon2.
-
Javaner schrieb:
@Michael E.
Was soll eigentlich das
if(zeichen >= 'A' && zeichen <= 'Z') zeichen = 'Z' - (zeichen - 'A');bedeuten?
Das wandelt doch zeichen in 'Z'+'A' - zeichen um

Nö, zählt, der wievielte Buchstabe im Alphabet "zeichen" ist und zieht dann diese Zahl von Z ab.
-
Simon2 schrieb:
Hmmmm, portabel das ist aber nicht mehr. In ASCII klappt das natürlich, aber z.B. in EBCDIC nicht. Auch wenn Portabilität nicht jedesmal notwendig ist, würde ich mir das gar nicht angewöhnen....
Also ich leb gut mit dieser Inkompatibilität. Du denkst, deins sei besser? Wieso benutzt du dann char? So bist du nicht mehr zu Unicode (der IMHO weiter verbreitet ist als EBCDIC) inkompatibel.
wenn man sich ein case sparen möchte, bietet sich ein Array eher an....
Als was?
Entweder so, wie Du schon beschrieben hast mit ein/aus-Map:
[...]Schau dir mal die Member von std::string an, die können dir viel Arbeit ersparen.
Oder mit direktem Mapping (unkomfortabler, dafür schneller):
[...]Wieso schneller? Es ist eh so unkomfortabel, dass mans erst in Extremsituationen benutzen sollte.
-
Michael E. schrieb:
...
Also ich leb gut mit dieser Inkompatibilität. ...Mag sein, da wir hier aber grundsätzlich Mulriplattformentwicklung machen (selber Code muß auf Windows, Unix und zOS (früher sogar noch OS2) laufen), verbietet sich das bei uns.
char benutze ich hier, damit die GrundIdee klarer wird. Insgesamt habe ich hier nur ein Beispiel und keinen "echten Code" dargestellt, an dem es noch eine Menge Verbesserungspotential gibt (u.a. die string-Möglichkeiten). Hier geht es um die Grundidee, "Buchstaben portabel in einem Programm zu verwenden" und daneben noch "Mapping via Arry statt switch-case" (OK, ein wenig auf de String als Container wollte ich auch noch hinweisen) - keinesfalls wollte ich alle verfügbaren Programmiertechniken und -stile darstellen.
Michael E. schrieb:
...
wenn man sich ein case sparen möchte, bietet sich ein Array eher an....
Als was?
als "switch-case" ?! ...
Michael E. schrieb:
...
...Oder mit direktem Mapping (unkomfortabler, dafür schneller):
[...]Wieso schneller? ...
Weil man pro Buchstaben nur einen Indexzugriff und keine Suche mehr hat.
Gruß,
Simon2.
-
Simon2 schrieb:
Mag sein, da wir hier aber grundsätzlich Mulriplattformentwicklung machen (selber Code muß auf Windows, Unix und zOS (früher sogar noch OS2) laufen), verbietet sich das bei uns.
Wer bist du, dass du hier die Regeln vorschreibst?
char benutze ich hier, damit die GrundIdee klarer wird. Insgesamt habe ich hier nur ein Beispiel und keinen "echten Code" dargestellt, an dem es noch eine Menge Verbesserungspotential gibt (u.a. die string-Möglichkeiten). Hier geht es um die Grundidee, "Buchstaben portabel in einem Programm zu verwenden" und daneben noch "Mapping via Arry statt switch-case"
Dann nenne ich dir noch die Grundidee, Code wiederzuverwenden.
Michael E. schrieb:
...
wenn man sich ein case sparen möchte, bietet sich ein Array eher an....
Als was?
als "switch-case" ?! ...
Das stand so ungünstig, dass ich das auf mich bezogen hab.
Weil man pro Buchstaben nur einen Indexzugriff und keine Suche mehr hat.
Hab mich bei dem Code verlesen. Dafür ist er noch viel unkompatibler. Du nimmst einfach mal an, dass der Zeichentyp 8 Bit groß ist. Ganz nebenbei machst du den Threadersteller auch noch mit Magic Numbers vertraut.
-
Mann mann mann !

Welche Laus ist Dir denn über die Leber gelaufen ?
"bei uns" = "In der Firma, in der ich arbeite".
Meine einzige Ergänzung zu Deinem Code ist, dass der "<>-Vergleich" nicht portabel (hier: zeichnesatzunabhängig) ist und dass man das auch mittels Mapping per Array machen kann.
Was daran bitteschön falsch oder ehrabschneidend ?Der Fragesteller arbeitet sich anscheinend noch in die Materie ein (was sehr gut ist) und da hielt ich den Verweis auf alle möglichen Stilfragen (UNICODE, magic numbers (habe das Buch auch gelesen, keine Sorge), ...) für unangemessen, den auf den Zeichensatz als solchen (wovon er offensichtlich noch nichts gehört hat) dagegen für thematisch passend.
Wenn Du meinst, dass Du ihm damit hilfst: Bitte schön - bring ihm alles bei, was Du weißt !
Gruß,
Simon2.