Problem mit seekg
-
Ich hab zwar keine Ahnung, was du da mit den Zahlen machen willst, aber das Einlesen geht so:
#include <iterator> #include <fstream> #include <vector> int main() { std::ifstream is("blah.txt"); std::vector<int> numbers(std::istream_iterator<int>(is), std::istream_iterator<int>()); }
-
Ungetestet, aber ist auch eher ein Kommentar, denn eine Verbesserung
#include <iostream> #include <fstream> // Jedes mal, wenn du C Header benutzt, tötet der Compiler ein Kätzchen // Jedes Mal, wenn du einen Header benutzt, den du nicht brauchst, tötet der Compiler ein Katzenmädchen // #include <stdio.h> // Siehe oben zu C-Headern // #include <stdlib.h> // Wurde durch was besseres ersetzt. // Jedes mal, wenn du einen systemspezifischen Header benutzt, den du nicht brauchst, bekommt Bill Gates einen Cent. Er ist damit angeblich reich geworden. // #include <Windows.h> #include <string> // Den habe ich zugefugt, weil ich ihn brauche #include <sstream> // Den auch. Als Ersatz für atoi aus stdlib.h using namespace std; // Jedes Mal, wenn du eine globale Variable benutzt, weint deine Mutter. // Jedes Mal, wenn du magische Zahlen benutzt, ist das kleine Jesuskind traurig. // int line = 0; // int zahl[37]={0}; // int i=0; // int z=0; // int zeilen=69621366; // int zeilen; // int prozent=0; // Für dieses Programm hast du deiner Mutter hoffentlich ein dickes Weihnachtsgeschenk gemacht. int main() { // Jedes mal, wenn du fstream nimmst, obwohl du ifstream meinst, betrinkt sich dein Vater. // Jedes Mal, wenn du eine Variable deklarierst und in der Zeile danach explizit initialisierst, anstatt gleich den passenden Konstruktor zu nehmen, weiß deine Oma, dass du sie nicht mehr lieb hast. // Jedes Mal, wenn du einer Variablen einen nichtssagenden Namen gibst, verhungert ein Hundebaby. // fstream f; // f.open("output.txt", ios::in); ifstream file("output.txt"); // Jedes Mal, wenn du Variablen am Funktionanfang deklarierst, anstatt da wo du sie brauchst, wird ein Pandabar vom Blitz getroffen. // Jedes Mal, wenn du char-Arrays statt std::string benutzt, ist Bjarne Stroustrup traurig. // char cstring[256]; // Jedes Mal, wenn du while(!x.eof()) benutzt, notiert dies der Weihnachtsmann auf seiner Liste. // Jedes Mal, wenn du sizeof auf ein Array anwendest, weißt du hoffentlich genau, was du da tust (ich gehe davon aus, dass dies nicht der Fall ist, auch wenn's hier richtig ist) // Jedes Mal, wenn du Postfix benutzt ohne den Rückgabewert zu benutzen, erfährt deine Grundschullehrerin, was du Nachts träumst. // while (!f.eof()) // { // f.getline(cstring, sizeof(cstring)); // zeilen++; // } unsigned num_lines = 0; { string line; while (getline(file, line)) ++num_lines; } cout << num_lines << " Zeilen erkannt.\nStarte zaehlen..." << endl; // Jedes Mal, wenn du ein Fehlerflag erkannt hast und weiter arbeitest, ohne es zu löschen, machst du etwas grundlegend falsch. // Jedes Mal, wenn du atoi benutzt, sage ich 314159265358979, wo du wohnst. Und das willst du wirklich nicht, dass der das weiß ,wenn du atoi benutzt. // Jedes Mal, wenn du eine Rechenoperation machst, die du gar nicht benutzt, wird dein Computer etwas langsamer. Permanent. // Außerdem: Siehe oben zu eof, postfix // while (!f.eof()) // { // f.getline(cstring, sizeof(cstring)); // int aktuell = atoi(cstring); // zahl[aktuell]++; // i++; // if(i%1000==0) // { // prozent = i*100/zeilen; // cout << "\r" << i << " von " << zeilen << " Zeilen ausgewertet." << flush; // } // } file.clear(); file.seekg(0, ios::beg); const int max_number = 37; int numbers[max_number]={0}; { string line; unsigned line_counter = 0; while (getline(file, line)) { stringstream lineparser(line); int value; line >> value; ++numbers[value]; ++line_counter; if(line_counter % 1000 == 0) cout << "\r" << line_counter << " von " << num_lines << " Zeilen ausgewertet." << flush; } } // Jedes Mal, wenn du eine Datei schließt, die sowieso gleich aus dem Scope geht, lässt die Polizei einen Mörder frei. // f.close(); // Jedes Mal, wenn du eine Zählschleife als while-Schleife schreibst, wird die Welt ein bisschen schlechter. Sieh, was du angerichtet hast! // Außerdem: Postfix, magische Zahlen. // while(z<=36) // { // cout << "\n" << z << ": " << zahl[z] << flush; // z++; // } for (int i = 0; i < max_number; ++i) cout << "\n" << i << ": " << numbers[i] << flush; // Ach, wozu das denn. Lern mit deinem Computer umzugehen. // cin.get(); // Jedes Mal, wenn du am Ende der main ein return 0 machst, zeigst du, dass du noch etwas über die Grundlagen von C++ zu lernen hast. // return 0; }Außerdem:
Jedes Mal, wenn du erst eine ganze Datei stückweise einliest, um danach den Fortschritt beim nochmaligen stückweisen Einlesen anzeigen zu können, fällt in China ein Sack Reis um und 38 Menschen sterben bei dem Unglück.
Jedes mal, wenn du in jeder Zeile eine Zahl stehen hast, dann die Zeile einliest, dann die gelesene Zeile in eine Zahl umrechnest, anstatt gleich eine Zahl einzulesen, bekommt ein Investmentbanker 1 Milliarde Euro vom Bundespräsidenten geschenkt.In diesem Sinne (auch ungetestet):
#include <iostream> #include <fstream> using namespace std; int main() { ifstream file("output.txt"); file.seekg(0, ios::end); streampos filesize = file.tellg(); cout << filesize << " Zeichen erkannt.\nStarte zaehlen..." << endl; const int max_number = 37; int numbers[max_number] = {0}; { int value; int line_counter = 0; while (file >> value) { ++number[value]; ++line_counter; if(line_counter % 1000 == 0) cout << "\r" << file.tellg()*100/filesize << "% ausgewertet." << flush; } } for (int i = 0; i < max_number; ++i) cout << "\n" << i << ": " << number[i] << flush; }Falls was nicht funktioniert oder unverständlich ist, melde dich.
-
Erstmal danke für die Antwort.
Ich blick bei dem Code aber nich durch, ich bin Anfänger
Außerdem gibt es mir einen Fehler aus:89 C:\Dev-Cpp\main.cpp no match for 'operator>>' in 'line >> value'
Und macht man mehrzeilige Kommentare nich besser mit /* */

-
BlackCubeX schrieb:
Erstmal danke für die Antwort.
Ich blick bei dem Code aber nich durch, ich bin Anfänger
Außerdem gibt es mir einen Fehler aus:89 C:\Dev-Cpp\main.cpp no match for 'operator>>' in 'line >> value'
Ups, da sollte auch lineparser stehen. Aber der zweite Code ist sowieso viel besser.
Und macht man mehrzeilige Kommentare nich besser mit /* */

Das ist dann aber doof zu schachteln. Weil gar nicht schachtelbar.
-
Im zweiten wurde number nicht deklariert.
Ich hätts ja gern selber gemacht, aber ich blick da wie gesagt nimmer durch.
-
Tippfehler, numbers. Das zweite ist doch erheblich einfacher, das erste ist doch bloß so kompliziert, weil ich deines nachgemacht habe und das war schon von Anfang an kompliziert (und du hast es selber geschrieben). Ansonsten: Frag konkret.
-
Ja klar, aber wenn ich das selber Stück für Stück schreibe versteh ich das auch besser

Ich hab mir das jetz noch ein paar mal durchgelesen und nun verstanden
Du hattest noch ein file.seekg(0, ios::beg); vergessen, aber nun geht alles.
Danke.
-
@SeppJ
Jedes mal wenn du versuchst Leute zum wahren C++ zu bekehren wird ein Stück Wissen in deinem Kopf durch Religion ersetzt.
Jedes mal wenn du dich dabei über total unwichtige Kleinigkeiten auslässt wird dein wahrer Nickname einer transzendenten Zahl ähnlicher.Aber mal ehrlich, einige der Punkte die du da bekrittelst sind genau vollkommen egal.
Und den IMO wichtigsten Bug hast du nichtmal erwähnt:
const int max_number = 37; int numbers[max_number]={0}; { string line; unsigned line_counter = 0; while (getline(file, line)) { stringstream lineparser(line); int value; line >> value; // Jedes mal wenn du Eingabedaten verwendest ohne sie passend zu validieren stirbt ein guter Programmierer ++numbers[value];
-
SeppJ schrieb:
// Jedes mal, wenn du fstream nimmst, obwohl du ifstream meinst, betrinkt sich dein Vater.
Worin besteht denn der Nachteil, wenn man z.B. statt ifstream fstream benutzt?
Ist die Ausführung von fstream langsamer, weil man damit lesen und schreiben kann?
-
Stichwort Vermeidung unnötiger Koppelung
fstream erweitert das Interface von ifstream, obwohl diese erweiterte Funktionalität überhaupt nicht genutzt wird.
Abgesehen davon benutzt ifstream standardmäßig openmode = ios_base::in, während es für fstream ios_base::in|ios_base::out ist. Folglich wird die Variante mit fstream bei schreibgeschützten Varianten Dateien fehlschlagen, wenn openmode nicht noch explizit angegeben wird.
-
Und man kriegt Compilerfehler, wenn man aus Versehen was ausgeben will, zum Beispiel sich mal mit << und >> vertut.