Alternativen zur replace Funktion
-
Stimmt. Korrigiert.
-
Gebt ihm mal ne vernünftige Antwort sonst fang ich an sie auf dem Handy zu tippen.
Lese hier nur Klugscheißerei und anfängerfeindliche Lösungen die die halbe stdlib nutzen.
-
Dann erlaube ich mir mal, einen Vorschlag zu unterbreiten, den der Threadersteller vermutlich nachvollziehen kann.
#include <iostream> #include <algorithm> using namespace std; char alphabet[52] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', };//uups, sollte lokal in der main() sein. int main() { srand(time(0)); random_shuffle(std::begin(alphabet), std::end(alphabet)); char ch; while(cin.get(ch)) { if('a'<=ch and ch<='z') cout<<alphabet[ch-'a']; else if('A'<=ch and ch<='Z') cout<<alphabet[ch-'A'+26]; else cout<<ch; } }Beispiel:
Das Pferd frisst keinen Gurkensalat. GrI iwvpn wpMIIW qvMBvB jOpqvBIrErW. Angela ist doof. HBcvEr MIW neew. So, jetzt nur noch raufinden, wie man das Programm beendet... fe, svWUW BOp BeDZ prOwMBnvB, gMv ArB nrI ipecprAA yvvBnvW... Irgendwie cin bescheid sagen, dass die Eingabe fertig ist. zpcvBngMv DMB yvIDZvMn IrcvB, nrII nMv bMBcryv wvpWMc MIW. Unter Linux drücke man dazu Strg+D. Unter Windows isses Strg+Z. XBWvp VMBOh npüDqv ArB nrUO fWpc+G. XBWvp PMBnegI MIIvI fWpc+a. Process returned 0 (0x0) execution time : 164.044 s Press ENTER to continue.Alternativ
if(islower(ch))//hoffentlich ist 'ü' nicht lower cout<<alphabet[ch-'a']; else if(isupper(ch)) cout<<alphabet[ch-'A'+26]; else cout<<ch;Und hoffentlich nicht
for(char ch;cin.get(ch);) cout<<(isalpha(ch)?alphabet[islower(ch)?ch-'a':ch-'A'+26]:ch);Junge, Junge, was treibt Swordfish dazu, sowas zu schreiben?
face->hit(desk);
-
Combum schrieb:
Tut mir leid Ethon ich verstehe den QC nicht. kannst du eventuell auskommentieren,
und mir die Zeilen angeben, die ich brauche, damit der Fehler nicht passiert? Außerdem bitte noch sagen an welche Stelle das gehört. Danke!
*lach*
Da ist Dir was entgangen, ich erklärs mal kurz:Swordfish hat erstmal ob Deines Code gefacepalmt aber selber mit seinem Code
schweren Unfug getrieben, alles unnötig oder unnötig kompliziert gemacht.Daraufhin hat iocc ihn parodiert und es auf eine sehr humorvolle Weise auf die Spitze gebracht: Alle Schleifen weggemacht, wie vor ein paar Jahren echt in Büchern empfohlen doch tatsächlich wurde. Der Name iocc spielt auf den ioccc an, http://www.ioccc.org den internationalen Wettbewerb um den möglichst unleserlichsten C-Quellcode.
Ethon hat applaudiert, weil ioccs Code so lustig unleserlich ist und technisch so ausgefuchst.
-
volkard schrieb:
Combum schrieb:
Tut mir leid Ethon ich verstehe den QC nicht. kannst du eventuell auskommentieren,
und mir die Zeilen angeben, die ich brauche, damit der Fehler nicht passiert? Außerdem bitte noch sagen an welche Stelle das gehört. Danke!
*lach*
Da ist Dir was entgangen, ich erklärs mal kurz:Swordfish hat erstmal ob Deines Code gefacepalmt aber selber mit seinem Code
schweren Unfug getrieben, alles unnötig oder unnötig kompliziert gemacht.Daraufhin hat iocc ihn parodiert und es auf eine sehr humorvolle Weise auf die Spitze gebracht: Alle Schleifen weggemacht, wie vor ein paar Jahren echt in Büchern empfohlen doch tatsächlich wurde. Der Name iocc spielt auf den ioccc an, http://www.ioccc.org den internationalen Wettbewerb um den möglichst unleserlichsten C-Quellcode.
Ethon hat applaudiert, weil ioccs Code so lustig unleserlich ist und technisch so ausgefuchst.
Ok, jetzt ist es klar, Danke.
Dein Code ist in der Tat sehr simpel, ich verstehe ihn!
Deine while schleife vergleicht den wert von ch mit den werten der ascii Tabelle, richtig?Und ja ich bin ein Anfänger, das macht aber nichts, da ich noch in der 9. Klasse bin (bald in die 10. komme) und aus Spaß programmiere.

Habt ihr alle Informatik studiert?
-
Ne. Programmieren lernst du vor allem selbstständig. Ich habe sehr viel durch dieses Forum und das Selbststudium von guten (!) C++-Büchern gelernt.
-
volkard schrieb:
Alle Schleifen weggemacht, wie vor ein paar Jahren echt in Büchern empfohlen doch tatsächlich wurde.
Das wird immer noch von vielen empfohlen. Also nicht *alle*, aber alle wo es einfach geht. Und es geht bei vielen der Schleifen die normalerweise drinnen gelassen werden recht einfach.
Combum schrieb:
Ethon hat applaudiert, weil ioccs Code so lustig unleserlich ist und technisch so ausgefuchst.
Ich finde ioccs Code gar nicht so unleserlich. Alles nur Gewohnheitssache, aber selbst wenn man es nicht gewohnt ist ist der Code für jmd. der halbwegs C++ kann nicht so schwer zu entziffern.
-
Combum schrieb:
Dein Code ist in der Tat sehr simpel, ich verstehe ihn!
Danke. Das ehrt mich.
Combum schrieb:
Deine while schleife vergleicht den wert von ch mit den werten der ascii Tabelle, richtig?
Ich würde es nicht so vereinfacht ausdrücken.
Zunächst mal wird in C++ gar nicht zwischen einem Zeichen und dessen ASCII-Wert unterschieden werden. Das Zeichen IST bereits eine Zahl (zwischen -128 und +127 oder zwischen 0 und 255, je nach Compiler).Falls Dir per Schreibtischtest gelingt, vorherzusagen, was die nächsten beiden Programme ausgeben, dann ist gänzlich jeder Zweifel beseitigt, wie das eigentliche Programm von mir funktioniert.
#include <iostream> int main() { for(char ch='a';ch<='z';ch+=2) std::cout<<ch; }#include <iostream> #include <string> using namespace std; int main() { string wort="annabella"; for(auto ch:wort) cout<<ch-'a'<<' '; }
-
Bumbum schrieb:
Da es noch nicht explizit erwähnt wurde: Sobald du alle Buchstaben einzeln in den Code schreibst, und sogar noch Gross-/Kleinschreibung und 2 nacheinander als Varianten, hast du etwas Grundlegendes im Programmieren nicht verstanden. Nämlich Codeduplikation zu vermeiden, indem man ähnlich aussehende Codestücke durch Abstraktion (Funktionen, Schleifen, ...) vereinheitlicht.
Harte Worte.

Also ich bin mir da nicht so sicher, wen ich gerne im Team haben würde.
char alphabet[52] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', };char alphabet[2*('z'-'a'+1)]; boost::copy(boost::join(boost::irange('a', static_cast<char>('z'+1)), boost::irange('A', static_cast<char>('Z'+1))), from.begin());char alphabet['z' - 'a' + 'Z' - 'A' + 2]; for(std::size_t i {}; i < alphabet.size(); ++i) alphabet[ i ] = (i > 'z' - 'a' ? 'A' : 'a') + i % ('z' - 'a' + 1);
-
Nicht zu vergessen
char alphabet[52]; std::iota( alphabet , alphabet + 26, 'a' ); std::iota( alphabet + 26, alphabet + 52, 'A' );int main() { for(char ch='a';ch<='z';ch+=2) std::cout<<ch; }Pshaw! Anfänger!
boost::copy( boost::irange('a', 'z', 2), std::ostreambuf_iterator<char>(std::cout) );
-
Arcoth schrieb:
Nicht zu vergessen
char alphabet[52]; std::iota( alphabet , alphabet + 26, 'a' ); std::iota( alphabet + 26, alphabet + 52, 'A' );Sehr schön. Endlich mal ein nicht gekünsteltes Iota-Beispiel

-
volkard schrieb:
#include <iostream> int main() { for(char ch='a';ch<='z';ch+=2) std::cout<<ch; }#include <iostream> #include <string> using namespace std; int main() { string wort="annabella"; for(auto ch:wort) cout<<ch-'a'<<' '; }Es kommt heraus.... *ascii tabelle googeln*, lass mal sehen...
beim ersten: c also Zahl 99 ←Ist das richtig?
beim zweiten weiß ich nicht was "auto ch:wort" macht.P.S. Ich habe nicht geschummelt, kannst ja mal vorbeikommen, mein IDE ist geschlossen!

-
Combum schrieb:
volkard schrieb:
#include <iostream> int main() { for(char ch='a';ch<='z';ch+=2) std::cout<<ch; }Es kommt heraus.... *ascii tabelle googeln*, lass mal sehen...
beim ersten: c also Zahl 99 ←Ist das richtig?Nee. 'a'==95 und 97=='c', das weißte ja.
Der operator<< stellt anhand das Typs der Variablen fest, wie die Zahl ausgegeben werden soll. Ist der Typ ein char, wird es als ASCII-Zeichen ausgegeben. Ist der Typ ein int, wird sie als Dezimalzahl ausgegeben.#include <iostream> using namespace std; int main() { int a=97; char b=98; int c='c'; char d='d'; cout<<a<<'\n';//ausgabe 97 cout<<b<<'\n';//ausgabe b cout<<c<<'\n';//ausgabe 99 cout<<d<<'\n';//ausgabe d }So, und nur haste im Programm eine ganz normale Schleife. Sie läuft von da bis dort mit jener Schrittweite und gibt immer mit dem operator<<(achte auf den Typ!) die Laufvariable aus.
-
Combum schrieb:
beim zweiten weiß ich nicht was "auto ch:wort" macht.
Dann möchte ich das zweite ändern zu
#include <iostream> #include <string> using namespace std; int main() { string wort="annabella"; for(string::iterator i=begin(wort);i!=end(wort);++i){ char ch=*i; int x=ch-'a'; cout<<x<<' '; } }oder
#include <iostream> #include <string> using namespace std; int main() { string wort="annabella"; for(size_t i=0;i!=wort.size();++i){ char ch=wort[i]; int x=ch-'a'; cout<<x<<' '; } }Combum schrieb:
P.S. Ich habe nicht geschummelt, kannst ja mal vorbeikommen, mein IDE ist geschlossen!

Fein. Ich denke, es könnte ganz lehrreich sein, mal ein wenig vom Ausprobieren anzukommen. Durch Selber-Durchdenken kriegt man ein viel besseres Gefühl dafür, wie der Computer geht und das wirste brauchen, um Dir Lösungen für kompliziertere Probleme einfallen zu lassen. Der Schreibtischtest wird Dein bester Freund werden.

-
[quote="volkard"][quote="Combum"]
volkard schrieb:
Nee. 'a'==95 und 97=='c', das weißte ja.

Auf meiner ascii tabelle ist a=97 und b=98 und c=99. Meine Tabelle: http://www.torsten-horn.de/techdocs/ascii.htm
(gehört nicht mir, ich benutze sie nur)Als ich gestern den Pc ausgemacht hab, ist mir eingefallen, dass die antwort nicht c sein kann, weil es ja ne schleife war.

Dann berichtige ich jetzt:1. cegikmopsuwy{ jedesmal wenn die schleife durchläuft wird geprüft, ob ch noch unter oder gleich z ist, dann wird eine zahl addiert welche ausgegeben dann ein Zeichen ergibt.
2. Ich ignoriere mal size_t i=0;i!=wort.size();
char ch=wort[i]; Verstehe ich auch nicht, denn wort war nicht als array definiert, nur als String.
Aber ich habe eine Vermutung:
Ausgabe: " ^M ^M ^A ^D ^K ^K " die leerzeichen gehen verloren wegen dem forum und dem spam schutz.
Wenn man wort aufteilt und dann in verschiedene chars "reinlegt"
die dann minus a rechnet und dann ausgibt sollte das herauskommen.
-
Combum schrieb:
volkard schrieb:
Nee. 'a'==95 und 97=='c', das weißte ja.

Auf meiner ascii tabelle ist a=97 und b=98 und c=99. Meine Tabelle: http://www.torsten-horn.de/techdocs/ascii.htm
(gehört nicht mir, ich benutze sie nur)Ups, ja, das meine ich.
Combum schrieb:
1. cegikmopsuwy{ jedesmal wenn die schleife durchläuft wird geprüft, ob ch noch unter oder gleich z ist, dann wird eine zahl addiert welche ausgegeben dann ein Zeichen ergibt.
Ganz genau. Aber 'a' ist noch drin und '{' nicht mehr. Also acegikmopsuwy
Combum schrieb:
2. Ich ignoriere mal size_t i=0;i!=wort.size();
char ch=wort[i]; Verstehe ich auch nicht, denn wort war nicht als array definiert, nur als String.Klappt aber auch. Die netten Leute haben den operator[] für strings so überladen, daß sie sich dahingehend wie Arrays anfühlen.
Combum schrieb:
Aber ich habe eine Vermutung:
Ausgabe: " ^M ^M ^A ^D ^K ^K " die leerzeichen gehen verloren wegen dem forum und dem spam schutz.
Wenn man wort aufteilt und dann in verschiedene chars "reinlegt"
die dann minus a rechnet und dann ausgibt sollte das herauskommen.^M sieht aber nicht wie ein int aus.
Die Ausgabe sollte sein
0 13 13 0 1 4 11 11 0Also a wird zu 0, b zu 1, c zu 2, e zu 4, l zu 11, n zu 13
"anabella" -> 0 13 13 0 1 4 11 11 0
-
Oh Stimmt, ich habe nicht darauf geachtet, dass int ausgegeben wird. aber wenn x ein char wäre dann wäre ich richtig.
Kannst du mir erklären wieso man überlädt und wie das geht?
-
Combum schrieb:
Oh Stimmt, ich habe nicht darauf geachtet, dass int ausgegeben wird. aber wenn x ein char wäre dann wäre ich richtig.
Kannst du mir erklären wieso man überlädt und wie das geht?Beispiel:
int main() { int arr[10]; for(int i=0;i<=10;++i){ arr[i]=0; cout<<arr[i]<<' '; } }Uups, das sind ja 11 Zahlen. Und das dumme dran ist, daß das Programm zufällig nicht abstürzt. Aber es könnte beim Kunden Blödsinn bauen. Ich will mich dagegen schützen. Also baue ich eine eigene Array-Klasse:
#include <iostream> #include <cassert> using namespace std; template<typename Data,int Size> class Array{ Data data[Size]; public: Data get(int i){ assert(0<=i and i<Size); return data[i]; } void set(int i,Data d){ assert(0<=i and i<Size); data[i]=d; } }; int main() { Array<int,10> arr; for(int i=0;i<=10;++i){ arr.set(i,0); cout<<arr.get(i)<<' '; } }Ausgabe
Combum: /home/volkard/.../main.cpp:14: void Array<Data, Size>::set(int, Data) [with Data = int; int Size = 10]: Assertion `0<=i and i<Size' failed. 0 0 0 0 0 0 0 0 0 0 Process returned -1 (0xFFFFFFFF) execution time : 0.002 s Press ENTER to continue.Perfekt, diesen Programmierfehler liefere ich nie wieder dem Kunden aus.
Aber so ist das Array doof zu benutzen. Also aufrüsen, zuerstmal benutze ich als Rückgabe eine Referenz auf das Array-Element.
#include <iostream> #include <cassert> using namespace std; template<typename Data,int Size> class Array{ Data data[Size]; public: Data& at(int i){ assert(0<=i and i<Size); return data[i]; } }; int main() { Array<int,10> arr; for(int i=0;i<10;++i){ arr.at(i)=i*i; } for(int i=0;i<10;++i){ cout<<arr.at(i)<<' '; } }deulich angenehmer.
Und jetzt überlade ich den Operator[]:
#include <iostream> #include <cassert> using namespace std; template<typename Data,int Size> class Array{ Data data[Size]; public: Data& operator[](int i){ assert(0<=i and i<Size); return data[i]; } }; int main() { Array<int,10> arr; for(int i=0;i<10;++i){ arr.operator[](i)=i*i; } for(int i=0;i<10;++i){ cout<<arr.operator[](i)<<' '; } }Wunderschön, oder?

Nee, in der main will ich natürlich die Aufrufweise auch als Operator stehen habe.
#include <iostream> #include <cassert> using namespace std; template<typename Data,int Size> class Array{ Data data[Size]; public: Data& operator[](int i){ assert(0<=i and i<Size); return data[i]; } }; int main() { Array<int,10> arr; for(int i=0;i<10;++i){ arr[i]=i*i; } for(int i=0;i<10;++i){ cout<<arr[i]<<' '; } }Jupp, ab jetzt muss ich keinen Programmierfehler mit Indexgrenzenüberschreitung mehr ausliefern und es fühlt sich trotzdem wie ein Array an.
Wollte schon immer mal wissen, was die Hälfte von drei siebentel ist.
#include <iostream> #include <cassert> using namespace std; class Bruchzahl{ public://sollte später private werden int z; int n; public: Bruchzahl(int zaehler,int nenner){ z=zaehler; n=nenner; } }; Bruchzahl operator*(Bruchzahl x,Bruchzahl y){ Bruchzahl z(x.z*y.z,x.n*y.n); return z; } void operator<<(ostream& out,Bruchzahl b){ out<<b.z<<'/'<<b.n; } int main() { Bruchzahl a(1,2); Bruchzahl b(3,7); Bruchzahl c=a*b;//Bruchzahl c=operator*(a,b); cout<<c;//operator<<(cout,b) }UUps!
cout<<c<<'\n';klappt nicht! Hab wiedermal kacke programmiert. Richtig geht es so:
ostream& operator<<(ostream& out,Bruchzahl b){ out<<b.z<<'/'<<b.n; return out; } … cout<<c<<'\n';//(cout<<c)<<'\n';//operator<<(operator<<(cout,c),'\n'); //die Rückgabe vom (cout<<c) ist ja genau wieder das cout, und kann dann in den <<'\n' gesteckt werden.
-
Du hast dir ja viel Mühe gegeben! Danke dafür

Man baut sich also seine eigenen Operatoren, welche weniger Fehler produzieren, weil sie anpassbar sind und mehr leserlich? Sollte so richtig sein.Btw, möchte jemand mein Pseudo- MatrixBildschirm -Programm haben?
