Zahlen richtig wiedergeben
-
Ja, da war ich leider noch nicht. Ist in dem Tutorial andscheindend schlecht geordnet
-
Jonas.M schrieb:
Ich nehme an das kommt von int zahl[4] und cin>> zahl. Das funktioniert so nur bei char
Schreib int zahl; statt int zahl[4], dann passt das auch. Denn du willst ja nur eine Zahl einlesen und nicht vier.
-
Michael E. schrieb:
Jonas.M schrieb:
Ich nehme an das kommt von int zahl[4] und cin>> zahl. Das funktioniert so nur bei char
Schreib int zahl; statt int zahl[4], dann passt das auch. Denn du willst ja nur eine Zahl einlesen und nicht vier.
Naja im konkreten Fall (Quersumme bilden) finde ich es günstiger, einen String einzulesen. Da erspart man sich elegant irgendwelches Rechengefrickel.
-
Die char[]-Variante geht nur leider vollständig an der Realität vorbei.
Wenn ich eine Zahl als Input haben will, lese ich eine Zahl ein und nichts, in dem vielleicht eine Zahl stehen könnte, wenn mir der User den Gefallen tut und eine positive ganze Zahl mit genau vier Ziffern ohne Vorzeichen und sonstigem Pipapo liefert und ich das nichtmal überprüfe. Übrigens kann ich mir gut vorstellen, dass das "Rechengefrickel" die eigentliche Aufgabe ist. Meiner Meinung nach ist das auch der Teil, bei dem der Fragesteller am meisten lernt und überhaupt nicht schwer. Doch wenn er es geschafft hat, hat er ein erstes Gefühl, wie man zu einer Aufgabenstellung einen Algorithmus entwirft und diesen implementiert.
Edit: Ach ja, Variablen werden nicht dekliniert. Da war wohl einer zu viel im Lateinunterricht
-
Wenn die Aufgabe heißt "geben Sie die Quersumme einer vom User eingegebenen Zahl aus" und man liefert etwas alá
int main() { std::string zahl; cin >> zahl; int quersumme = 0; for(int i = 0; i < zahl.size(); ++i) quersumme += zahl[i] - '0'; cout << quersumme << endl; }
finde ich das eine sehr elegante Lösung. Und warum sollte man sich auch die Arbeit machen, den eingelesenen Ziffernstrom erst in einen int und dann wieder zurück in einen Ziffernstrom zu verwandeln?
-
mhm schreibfehler
deklarieren war gemeintja die lösung mit der for kommt erst in der nächsten Aufgabe
und nochmal eine Lösung zur ersten Aufgabe...
#include <iostream> #include <string> using namespace std; int main() { string zahl,Quersumme; cin>> zahl; Quersumme=zahl[0]+zahl[1]+zahl[2]+zahl[3]; cout<<"Die Zahl lautet "<<zahl[0]<<zahl[1]<<zahl[2]<<zahl[3]<<"und deren Quersumme lautet " << Quersumme<< endl; system("Pause"); }
wieder das misteriöse zeichen ^^
-
ipsec schrieb:
finde ich das eine sehr elegante Lösung.
Ich nicht.
Und warum sollte man sich auch die Arbeit machen, den eingelesenen Ziffernstrom erst in einen int und dann wieder zurück in einen Ziffernstrom zu verwandeln?
LOL, damit hast du ja mal überhaupt nichts zu tun.
cin >> zahl; cout << zahl;
Das ist exakt derselbe Code, egal, ob zahl ein int oder ein string oder was auch immer ist.
Andersrum kann ich genauso fragen: Warum sollte man sich die Mühe machen und von ASCII-Zeichen in Zahlen umrechnen? Du siehst ja, welche Probleme der OP damit hat.
-
Aber vor der Verwendung eines char[]-Strings sollte doch wenigstens erleutert werden, dass diese mit einem '\0' abgeschlossen werden und daher ein Zeichen mehr brauchen.
Hin oder her, im Prinzip ist das schon recht elegant, anstatt for kannst du auch while nehmen oder du schreibst es halt [0]+[1]+[2]+[3], zum üben Jacke wie Hose.
Da das Tutorial offensichtlich noch nicht einmal bei for angekommen ist, wirst du dir wohl auch über die Validierung der Eingabe keine Gedanken machen müssen. Weil weder die Anzahl noch die Art (Zahl oder Buchstabe) der eingegebenen Zeichen wird überprüft. Das könnte recht Fehleranfällig werden...
Übrigens die Eingabe als int bzw. uint hätte schon dem Charme, dass eben dieses dann ganz einfach wird bzw. entfällt. Und es gibt ja auch sowas wie inttostr (oder so ähnlich), aber ob das schon vor for dran war...
-
Heimelchen schrieb:
Übrigens die Eingabe als int bzw. uint hätte schon dem Charme, dass eben dieses dann ganz einfach wird bzw. entfällt.
Eben, die Validierung wird einem geschenkt.
Und es gibt ja auch sowas wie inttostr (oder so ähnlich), aber ob das schon vor for dran war...
Das braucht man doch gar nicht.
-
Michael E. schrieb:
Und warum sollte man sich auch die Arbeit machen, den eingelesenen Ziffernstrom erst in einen int und dann wieder zurück in einen Ziffernstrom zu verwandeln?
LOL, damit hast du ja mal überhaupt nichts zu tun.
Doch durchaus. Die Umwandlung Ziffernstrom -> Zahl macht natürlich
cin
, aber es wird eben gemacht. Und es ist sinnlos, wenn man danach die Zahl nur wieder in einzelne Ziffern zerlegt.
Außerdem wüsste ich nicht, was anint main() { int zahl, quersumme = 0; cin >> zahl; while(zahl > 0) { quersumme += zahl % 10; zahl /= 10; } cout << quersumme << endl; }
eleganter sein sollte, ganz davon abgesehen, dass es unperformanter ist.
Die Eingabevalidierung muss ich natürlich bei der string-Variante selber machen, muss ich aber sonst auch, spätestens wenn der User auf die Idee kommen könnte,
123.456
mit Erwartung des korrekten Ergebnisses einzugeben.
-
Michael E. schrieb:
Heimelchen schrieb:
Übrigens die Eingabe als int bzw. uint hätte schon dem Charme, dass eben dieses dann ganz einfach wird bzw. entfällt.
Eben, die Validierung wird einem geschenkt.
Und es gibt ja auch sowas wie inttostr (oder so ähnlich), aber ob das schon vor for dran war...
Das braucht man doch gar nicht.
Ahja? Gibts ne Quersummenfunktion? Oder möchtest du dir jede Stelle "Rausdividieren"? Dann ist es wohl eher Geschmackssache, was eleganter ist. Von der Performance her wird beides ähnlich sein...
-
ipsec schrieb:
Michael E. schrieb:
Und warum sollte man sich auch die Arbeit machen, den eingelesenen Ziffernstrom erst in einen int und dann wieder zurück in einen Ziffernstrom zu verwandeln?
LOL, damit hast du ja mal überhaupt nichts zu tun.
Doch durchaus. Die Umwandlung Ziffernstrom -> Zahl macht natürlich
cin
Wie kann man sich in so kurzer Zeit selbst widersprechen?
aber es wird eben gemacht.
Na und?
Außerdem wüsste ich nicht, was an [...] eleganter sein sollte
Es wird auf Zahlen operiert. Außerdem Lerneffekt blabla => kannst du oben nachlesen.
ganz davon abgesehen, dass es unperformanter ist.
Erstens: Beweisen. Zweitens: Na und?
Die Eingabevalidierung muss ich natürlich bei der string-Variante selber machen, muss ich aber sonst auch, spätestens wenn der User auf die Idee kommen könnte,
123.456
mit Erwartung des korrekten Ergebnisses einzugeben.Bullshit. Quersummen sind nur auf natürlichen Zahlen definiert.
-
Michael E. schrieb:
ipsec schrieb:
Michael E. schrieb:
Und warum sollte man sich auch die Arbeit machen, den eingelesenen Ziffernstrom erst in einen int und dann wieder zurück in einen Ziffernstrom zu verwandeln?
LOL, damit hast du ja mal überhaupt nichts zu tun.
Doch durchaus. Die Umwandlung Ziffernstrom -> Zahl macht natürlich
cin
Wie kann man sich in so kurzer Zeit selbst widersprechen?
Der User gibt ein: '1' '2' '3' '4',
cin
macht daraus 1234. Danach macht man aus 1234 wieder 1 2 3 4 um die Quersumme zu bilden. Das kann man sich sparen bzw. dahin kommt man leichter.Michael E. schrieb:
aber es wird eben gemacht.
Na und?
Performance? Unnötiger Aufwand? Da fällt dir sicher was ein.
Michael E. schrieb:
Außerdem wüsste ich nicht, was an [...] eleganter sein sollte
Es wird auf Zahlen operiert. Außerdem Lerneffekt blabla => kannst du oben nachlesen.
Der TE lernt C++ und nicht Algebra. Warum sollte man eine Quersumme immer mit Mitteln der Mathematik ermitteln, wenn es ausgehend von der Darstellungsform viel effizientere Möglichkeiten gibt?
Michael E. schrieb:
ganz davon abgesehen, dass es unperformanter ist.
Erstens: Beweisen. Zweitens: Na und?
Hab jetzt leider keinen Compiler, aber sowohl Einlesen einer Zahl, als auch Modulo und Division sind relativ teure Operationen im Vergleich zum simplen Subtrahieren und Addieren. Und mit der "na und?"-Einstellung kommst du wohl nicht weit. Sicher kann man es mit der Optimierung übertreiben, aber bei nicht eingeschränkter Lesbarkeit sollte man doch die performantere Variante wählen. Ich nehme auch nicht
vector
, wenn ichset
will, weil ich mir sage "Na und? Ob ich mit O(n) oder O(log n) suche, ist doch egal".Michael E. schrieb:
Die Eingabevalidierung muss ich natürlich bei der string-Variante selber machen, muss ich aber sonst auch, spätestens wenn der User auf die Idee kommen könnte,
123.456
mit Erwartung des korrekten Ergebnisses einzugeben.Bullshit. Quersummen sind nur auf natürlichen Zahlen definiert.
Richtig. Dem in diesem Fakt unwissenden User ist aber mit 6 als Ausgabe (weil
cin
beim ersten Nicht-Ziffern-Zeichen aufhört, wenn ich mich jetzt richtig erinnere) ebenso wenig geholfen wie mit 21+'.'-'0' (was auch immer das jetzt ist). Also brauch man in beiden Fällen eine Validierung, die über die voncin
hinausgeht.
-
Jaja, erzählst mir hier einen von Performance-Mikro-Nano-Optimierungen und benutzt std::string
Na wenn du meinst, dass ich mit meiner Einstellung nicht weit komme, dann bleib halt bei deiner Meinung. Ich weiß auf jeden Fall, was absolut tödlich für Anfänger ist: vorzeitige Optimierung.
-
Ich habe dir mal eine kleine Einführung verfasst,
hoffe sie hilft dir weiter#include <iostream> using namespace std; int main() { /* int --> Für 1 Ganzzahl */ int i = 7; /* int[] --> int-Array --> Für mehrere Ganzzahlen */ int i_array[4] = {15,7,65,-10}; /* char --> Für 1 Zeichen Zeichen werden in einzelnen Hochkommas eingeschlossen. Ein Zeichen wird eindeutig durch einen sog. ASCII-Wert beschrieben. Welches Zeichen welchen ASCII-Wert hat, kannst du aus einer ASCII-Tabelle entnehmen. Ein ASCII-Wert ist wiederum 1 Ganzzahl. */ char c = 'z'; // Du kannst bei char entweder ein Zeichen angeben, ... c = 122; // ... oder explizit den ASCII-Wert. ( 122 = 'z' ) /* char[] --> char-Array --> Für mehrere Zeichen bzw. 1 Zeichenkette. Stehen mehrere Zeichen hintereinander, spricht man von einer sogenannten Zeichenkette. Zeichenketten werden in doppelte Hochkommas eingeschlossen. Willst du das Array als Zeichenkette ansprechen, musst du am Schluss der Zeichenkette ein Terminierungszeichen '\0' angeben, welches die Zeichenkette beendet. Hantierst du ausschließlich mit den einzelnen Zeichen im Array, brauchst du das Terminierungszeichen nicht. */ char c_array_1[] = "C++"; // Initalisierung mit Zeichenkette. --> Terminierungszeichen ist automatisch mit dabei. char c_array_2[] = {'C','+','+','\0'}; char c_array_3[] = {'C','+','+'}; cout << c_array_2 << endl; // Darfst du, weil Terminierungszeichen angegeben. // cout << c_array_3 << endl; // Darfst du nicht, da kein Terminierungszeichen. cout << c_array_3[0] << c_array_3[1] << c_array_3[2] << endl; // Du musst nun Zeichen für Zeichen ausgeben. /* Das Zeichen '0' hat den ASCII-Wert 48. Willst du aus dem Zeichen '0' nun die Ganzzahl 0 machen, musst du von dem Zeichen '0' 48 subtrahieren: 0 = '0' - 48 oder 0 = '0' - '0' Das Zeichen '1' hat den ASCII-Wert 49, Willst du aus dem Zeichen '1' nun die Ganzzahl 1 machen, subtrahierst du wieder 48 bzw. '0': 1 = '1' - 48 oder 1 = '1' - '0' etc... */ cout << '0' - 48 << endl; cout << '0' - '0' << endl; cout << '1' - 48 << endl; cout << '1' - '0' << endl; /* Welches Zeichen welchen ASCII-Wert hat, kannst du ganz einfach herausfinden, indem du das Zeichen zu einem ganzzahligen Datentypen castest. */ cout << "ASCII-Wert von 'z' = " << static_cast<int>('z') << endl; /* Was du nun beachten musst: Bevor du anfängst du rechnen, musst du das Zeichen in eine Ganzzahl transformieren. */ string zahl; do { cin >> zahl; } while(zahl.length() != 4); // Nur 4-stellig zulassen. int ziffer[4] = {}; // Alle 4 Ganzzahlen-Elemente werden mit 0 initialisiert. ziffer[0] = zahl.at(0) - 48; ziffer[1] = zahl.at(1) - 48; ziffer[2] = zahl.at(2) - 48; ziffer[3] = zahl.at(3) - 48; int quersumme = ziffer[0] + ziffer[1] + ziffer[2] + ziffer[3]; cout << "Quersumme der Zahl " << zahl << " ist " << quersumme << "."; cin.sync(); cin.get(); return 0; }
mfg Dweb
-
ipsec schrieb:
Hab jetzt leider keinen Compiler, aber sowohl Einlesen einer Zahl, als auch Modulo und Division sind relativ teure Operationen im Vergleich zum simplen Subtrahieren und Addieren.
Ah, jettzt kommen Fachargumente. hihi.
Da geschieht keine Division durch 10, sondern eine Multiplikation, die hat 6-8 Takte, wenn man sich einen modernen Prozessor leisten kann. das new für den string hat Hunderte. Die bei nur vierstelliger Zahl aufzuholen dürfte nicht klappen.
Außerdem wollte der Prof doch sicherlich den Modulo-Operator vertiefen. Warum sich querstellen?
Es hat ja auch keiner das Hochschultypische EVA-Prinzip angezweifelt und while(isdigit(ch=cin.get())qs+=ch-'0'; oder sowas gevorschlagt.
-
Es waere doch auch eine Idee wenn die Zahl die der benutzer geschrieben hat in einer char variable gespeichert wird.
Diese wird dann wiederum Zeichen fuer Zeichen in eine zweite char variable addiert
wird.Waehrend diesem schritt wird von der dezimal Zahl jeder Zahl 48 abgezogen damit kaeme dann bei dem Zeichen '1' der dezimal wert '01' also das Zeichen 'SOH^A'
Bei der Ausgabe des addierten Buchstaben schreibt man aber 'static_cast<int>()' (die variable in der Klammer) und schon wird die quersumme der eingegebenen Zahl gezeigT
Beispeil:
[cpp]
#include <iostream>int main()
{
char zahl[5];std::cout << "Geben sie eine vierstellige Zahl ein: " << std::endl;
std::cin >> zahl;char quersumme;
quersumme = (static_cast<int>(zahl[0]) - 48) + (static_cast<int>(zahl[1]) - 48) + (static_cast<int>(zahl[2]) - 48) + (static_cast<int>(zahl[3]) -48);std::cout << "Ihre Zahl war: " << zahl << " Die Quersumme lautet: " << static_cast<int>(quersumme) << std::endl;
}
[cpp]