Brüche (z/n) zeilenweise aus datei einlesen
-
Hey
Ich suche schon seit Stunden nach einer Lösung, aber so richtig fündig werde ich nicht. Überall steht was Anderes, außerdem will ich das Ganze ja nachvollziehen können.
Ich soll Brüche aus einer Datei einlesen können, diese soll in etwa so aussehen:1/1 1/2 24/92 3/1 ...
Ich habe also pro Zeile einen Bruch stehen.
Am Ende möchte ich Zähler und Nenner in einer Variable (long int) haben.
Wie bekomme ich es also hin, das ich die Zahl vor, und die Zahl nach dem Bruchstrich in eine Variable speichern kann (mit denen rechne ich dann weiter ...), dann springe ich zur nächsten Zeile und speichere die nächsten zwei Werte usw., bis die letzte Zeile erreicht ist.Ich hoffe ihr versteht wie ich das meine
-
Stundenlang? Es gäbe zwar auch elegantere Lösungen, aber für folgendes braucht man nur das Wissen aus den ersten beiden Kapiteln eines jeden C++-Buchs.
cin >> zaehler >> bruchstrich >> nenner;
Wobei bruchstrich eine char-Variable ist.
-
Ich vermute, dass du genau danach suchst, wie man Brüche aus Dateien einlesen kann. Solche sehr speziellen Fragen und Antworten / Lösungen wirst du aber meistens nie finden, da mit halbwegs guten C++ Kenntnissen man das selber programmieren kann.
Du müsstest z.B. nach soetwas suchen wie "Wie öffne ich eine Datei".
Auf Youtube kann ich dir die Tutorials von Brotcrunsher und Bytes'n'Objects heißt er glaub ich, empfehlen.Als kleine Beispiellösung hätte ich folgendes, eigentlich selbsterklärendes Programm:
#include <iostream> #include <string> #include <fstream> #include <vector> #include <exception> // zahlen als character char numbers[]{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' }; // funktion zum ausgeben template<typename T> void call(T data) { std::cout << data << std::endl; } struct Fraction { // zähler long numerator; // nenner long denominator; // standard konstruktor wird wegen std::vector benötigt Fraction() { numerator = 1; denominator = 1; } Fraction(const std::string& input) { std::string numeratorString = "", denominatorString = ""; bool slashReached = false; // gehe jeden character in der eingelesenen zeile durch for (int i = 0; i < input.length(); i++) { // überprüfe, ob der character eine zahl oder schrägstrich ist for (int j = 0; j < 10; j++) { // wurde der schrägstrich noch nicht erreicht, füge die zahl dem zähler hinzu if (input[i] == numbers[j] && !slashReached) numeratorString += numbers[j]; // wurde der schrägstrich erreicht, füge die zahl dem nenner hinzu else if (input[i] == numbers[j] && slashReached) denominatorString += numbers[j]; // speichere es, wenn der schrägstrich erreicht wurde else if (input[i] == '/') slashReached = true; else throw std::exception("zeile konnte nicht in bruch umgewandelt werden"); } } // umwandlung von string in long numerator = std::stol(numeratorString); denominator = std::stol(denominatorString); } // überprüfung, ob ein character eine zahl beinhaltet static bool isNumber(char number) { for (int i = 0; i < 10; i++) { if (number == numbers[i]) { return true; } } return false; } // überprüfung, ob eine zeile ein bruch ist static bool isFraction(const std::string& input) { for (int i = 0; i < input.length(); i++) { for (int j = 0; j < 10; j++) { if (isNumber(input[i]) || input[i] == '/') { break; } else { return false; } } } return true; } // überladener ausgabe operator friend std::ostream& operator<<(std::ostream& out, Fraction fraction) { out << fraction.numerator << "/" << fraction.denominator; return out; } }; int main(int argc, char** argv) { // erzeuge einen input stream der datei datei.txt und öffne sie std::ifstream file("datei.txt"); // dynamisches array zum speichern der brüche std::vector<Fraction> fractions(0); // wenn die datei geöffnet wurde if (file.is_open()) { std::string line; // lese eine zeile des input streams und speichere die zeile in line while (std::getline(file, line)) { // entspricht die zeile einem bruch if (Fraction::isFraction(line)) { // erstelle einen bruch Fraction fraction(line); // füge ihn dem array hinzu fractions.push_back(fraction); } } } else { // sonst gib eine fehlermeldung aus call("Konnte die Datei nicht oeffnen."); } // gib alle brüche aus for (auto& fraction : fractions) call(fraction); system("pause"); return 0; }
-
Da steht so viel Quatsch, das würde ich nicht Lösung nennen...
-
DocShoe schrieb:
Da steht so viel Quatsch, das würde ich nicht Lösung nennen...
Dann kannst du es gerne berichtigen, wäre doch gut für ihn, wenn er eine bessere Lösung bekommen würde.
-
Solix0x schrieb:
Dann kannst du es gerne berichtigen, wäre doch gut für ihn, wenn er eine bessere Lösung bekommen würde.
Struct und vector sind schon mal gut, kombiniert mit SeppJs Vorschlag ergäbe das
#include <fstream> #include <iostream> #include <vector> struct Fraction { // zähler long numerator; // nenner long denominator; // Fraction() : numerator(1), denominator(1) {} // nicht nötig }; std::istream& operator>>(std::istream& in, Fraction& f) { char slash; in >> f.numerator >> slash >> f.denominator; return in; } std::ostream& operator<<(std::ostream& o, Fraction& f) { o << f.numerator << '/' << f.denominator; return o; } int main() { using namespace std; vector<Fraction> fractions; ifstream datei("fractions.txt"); if(!datei.is_open()) { cout << "Die Datei nicht geoeffnet werden.\n"; return 0; } for(Fraction f; datei >> f;) { fractions.push_back(f); cout << f << '\n'; } }
Der TE wollte das in anderer Form haben, das bleibt ja noch als Übung.
-
In dem
operator>>
sollte man aber noch prüfen, dass der gelesene Slash wirklich ein solcher war und ansonsten das failbit setzen.
-
Hallo Solix0x,
Solix0x schrieb:
Auf Youtube kann ich dir die Tutorials von Brotcrunsher und Bytes'n'Objects heißt er glaub ich, empfehlen.
wenn Du diese Videos gesehen hast, warum liest Du dann einen Bruch als String in den Speicher und fängst dann zu Fuß an,ihn als Zahl zu interpretieren? Die Videos zeigen doch schon früh - so zwischen 6.-8.Folge - wie man Zahlen einliest.
Wie kommst Du zu getline und string-Fieselei? Wird das dort in späteren Videos so gezeigt? Die eine Zeile, die SeppJ vorgeschlagen hat, ersetzt ungefähr 2/3 Deines Codes.
Gruß
Werner