Anzahl der Zeichen in einer Textdatei auslesen?
-
Googlen will gelernt sein.
Vierter Link bei Google: c++ size of a file:
http://stackoverflow.com/questions/5840148/how-can-i-get-a-files-size-in-cEtwas frickelig
Pardon?
-
Arcoth schrieb:
Etwas frickelig
Pardon?
Also schön finde ich die Methode nicht.
-
-
Belli schrieb:
...
Es ging nicht darum, das mir das Wort fremd war. Und das erste Ergebnis auf Google definiert es mit "widerspenstig". Diese Methode ist nicht widerspenstig, und genau deswegen habe ich ja widersprochen.
Also schön finde ich die Methode nicht.
Ich auch nicht, aber deswegen ist sie nicht frickelig. Sie ist nur leider nicht so direkt.
Was spricht überhaupt gegen einensize()
-Member von filebuf?
-
Bei Unicode hilft dann doch aber nur Zeichen zählen, oder?
-
Arcoth schrieb:
Belli schrieb:
...
Es ging nicht darum, das mir das Wort fremd war. Und das erste Ergebnis auf Google definiert es mit "widerspenstig".
Dann würd es ja so ein bisschen auf Dich passen ...
Aber so wie ich Dich mittlerweile einschätze, und das ist durchaus positiv gemeint, würdest Du Dich doch nicht mit dem ersten Link zufrieden geben und noch ein paar weitere aufrufen, um Dir ein Gesamtbild zu machen ...
Dass es Dir da gar nicht drum ging, hab ich mir zwar gedacht, aber ich wollte nichts in Dein Posting hineininterpretieren und hab es deshalb so genommen, wie es dort stand - so gut ich konnte, jedenfalls.
-
CppNeuland schrieb:
Bei Unicode hilft dann doch aber nur Zeichen zählen, oder?
Bei UTF-8 und UTF-16, ja.
-
würdest Du Dich doch nicht mit dem ersten Link zufrieden geben und noch ein paar weitere aufrufen, um Dir ein Gesamtbild zu machen ...
Und wo ist der nächste Link? Der Rest der Google-Ergebnisse (außer vllt. dem) ist wertlos. Außerdem beherrsche ich die deutsche Sprache, und weiß sehr gut, was frickelig heißt. Dazu brauche ich keine Bestätigung von irgendeinem Online-Wörterbuch. (Können wir diese merkwürdige OT-Diskussion nun bitte beenden?)
Dass es Dir da gar nicht drum ging, hab ich mir zwar gedacht, aber ich wollte nichts in Dein Posting hineininterpretieren und hab es deshalb so genommen, wie es dort stand - so gut ich konnte, jedenfalls.
Nun, jetzt weißt du es - ich habe lediglich SeppJ widersprechen wollen.
-
Du kannst die Datei natuerlich auch gleich von hinten oeffnen.
ifstream input; input.open("Example.txt", ios::ate); unsigned int ctr = input.tellg(); input.close();
Ansonsten fuer Windows kriegst du hier die Filesize raus.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365739(v=vs.85).aspx
-
Arcoth schrieb:
Und wo ist der nächste Link?
Mhm, vielleicht hab ich Dich doch überschätzt?
Aber einmal helfe ich Dir noch:
Ohne das jetzt selbst überprüft zu haben, behaupte ich mal, er ist direkt unter dem ersten.
-
Das reicht jetzt. Ich werde hier nicht meine Zeit damit verschwenden, dir irgendwas zu beweisen.
ifstream input; input.open("Example.txt", ios::ate);
Den Konstruktor von
ifstream
nicht ignorieren.ifstream input("Example.txt", ios::ate);
Schließen muss man die Datei auch nicht, das macht der Destruktor. Und statt
unsigned int
den richtigen Typ nehmen.
-
Arcoth schrieb:
Das reicht jetzt. Ich werde hier nicht meine Zeit damit verschwenden, dir irgendwas zu beweisen.
ifstream input; input.open("Example.txt", ios::ate);
Den Konstruktor von
ifstream
nicht ignorieren.ifstream input("Example.txt", ios::ate);
Schließen muss man die Datei auch nicht, das macht der Destruktor. Und statt
unsigned int
den richtigen Typ nehmen.Hi,
was ist denn der richtige Datentyp fuer tellg?Ouf overflow habe ich das dazu gefunden: http://stackoverflow.com/questions/10065323/how-to-collect-and-store-tellp-tellg-return-types
Was den Konstruktor angeht ist doch der einzige Unterschied zwischen deinem Objekt zu meinem, dass ich das ifstream-Objekt nicht gleich mit einer Datei assoziiere, oder?
Ich habe irgendwo gelesen, dass man sobald man mit einer Datei fertig ist sie so schnell wie moeglich wieder schliessen soll. Der Destruktor des ifstream Objektes wird ja erst aufgerufen, wenn das Objekt "out of scope" gegangen ist.
Oder brauch ich mir die Muehe nicht machen?
-
Vielen Dank für die vielen Antworten.
Ich habe jetzt
ifstream file( "example.txt", ios::binary | ios::ate); return file.tellg();
übernommen.
Wie kann ich denn nun aber diesen Wert einer Variablen zuweisen?
-
Ich muss mich korrigieren. Diese Lösung scheint nicht zu funktionieren.
Sobald ich
ifstream file( source_file );
durch
ifstream file( source_file, ios::binary | ios::ate ); return file.tellg();
ersetze, stürzt das Programm an der Stelle ab.
-
djnforce schrieb:
ersetze, stürzt das Programm an der Stelle ab.
Das kann hunderte Ursachen haben. Siehe:
http://www.c-plusplus.net/forum/304133Wie kann ich denn nun aber diesen Wert einer Variablen zuweisen?
Was hast du vor? Kannst du überhaupt C++?
-
Ich bin C++ Anfänger.
Ich habe eine Textdatei mit über 10 000 Zeilen, aus der ich nur bestimmte Zahlen benötige.
Diese werden untereinander in einer anderen Textdatei gespeichert. Das funktioniert super.Das ganze dauert aber ca. 1-2 Minuten und ich möchte den Nutzer nicht im ungewissen über den Fortschritt lassen.
Deshalb möchte ich zu Anfang gerne wissen, wie viele Character die Ausgangsdatei hat um diese Zahl mit der zur Zeit durchsuchten Anzahl an Character zu vergleichen.
So kann ich dann immer ausgeben lassen:
10% 20% usw.Der gesamte Code:
// This program will find specific information in the huge tripfile. // If you have some questions please feel free to ask ... // build: 13.11.2013 #include <fstream> #include <string> #include <iostream> #include <iterator> #include <sstream> #include <math.h> #include <stdio.h> using namespace std; // "ignore_until" forces to ignore all words until a specific word is found void ignore_until(istream& is, const string& delim) { string data; while (is.good()) { data.push_back((char) is.get()); if (data.find(delim) != string::npos) return; } } int main() { string source_file; string target_file; int opt; float size; cout << "Please choose one option:\n\n1- GPS coordinates \n2- GPS coordinates & fieldstrengths \n3- GPS coordinates & fieldstrengths & frequencies \n4- GPS coordinates & fieldstrengths & frequencies & Programm Identification\n"; cin >> opt; cout << "\n\nsource file (example.txt):" << endl; cin >> source_file; // type name of source file cout << "\ntarget file (further_example.txt):" << endl; cin >> target_file; // type name of target file cout << "\nmerging still in progress (it may take a few minutes), please wait..." << endl; ifstream file( source_file ); //size = file.tellg(); if( !file.is_open() ) // could the file be opened? return -1; ofstream new_file( target_file ); // In this file we would like to save our data new_file.setf(ios::fixed); // no scientific output // what we searching for: const string what_reference = "<proxyf"; // Our search will start at the head of our source file const string what_coord = "Coord:("; // we are looking for GPS coordinates const string what_field = "Fieldstrength : "; // we are looking for FM Fieldstrength const string what_freq = "Frequency : "; // we are looking for related frequency const string what_pi = "PI : "; // PI --> Program Identification. Is a unique number for each radio station. You can check which station name is behind the number under http://www.fmlist.org (click on "continue as guest") string str; // do we need to check if we are starting in the head of the file for(char c; file.get(c);) // each time the loop pass we read one character { str += c; // This character we attach to the string if( str == what_reference ) // if this string matches the variable "what_reference" we know that we are in the file header and can start to read { //#### read coordinates ignore_until(file, what_coord); // ignore everything until "what_coord" appears double x; file >> x; // read first coordinate file.ignore( 1 ); // Ignore the comma double y; file >> y; // read second coordninate //#### read frequency ignore_until(file, what_freq); // ignore everything until "what_freq" appears double freq; file >> freq; // read frequency //#### read PI --> Program Identification. Is a unique number for each radio station. You can check which station name is behind the number under http://www.fmlist.org (click on "continue as guest") ignore_until(file, what_pi); // ignore everything until "what_pi" appears string pi; file >> pi; // read PI //#### read fieldstrenth ignore_until(file, what_field);// ignore everything until "what_field" appears string value; file >> value; // read fieldstrength // write data to file if( file ) // was reading successful ? { // reading was successful --> write data to file while recalculating coordinates (coordinate transformation) if ( opt == 4 ) new_file << y * (360 / pow(2,32)) << ',' << x * (360 / pow(2,32)) << ',' << value << ',' << freq*0.001 << ',' << pi << '\n'; else if ( opt == 3 ) new_file << y * (360 / pow(2,32)) << ',' << x * (360 / pow(2,32)) << ',' << value << ',' << freq*0.001 << '\n'; else if ( opt == 2 ) new_file << y * (360 / pow(2,32)) << ',' << x * (360 / pow(2,32)) << ',' << value << '\n'; else if ( opt == 1 ) new_file << y * (360 / pow(2,32)) << ',' << x * (360 / pow(2,32)) << '\n'; } str.clear(); // we clear str and start again } else if( str.length() == what_coord.length()) { // its necessary, don't ask why :-) str.erase( 0, 1 ); } } }
-
djnforce schrieb:
Das ganze dauert aber ca. 1-2 Minuten und ich möchte den Nutzer nicht im ungewissen über den Fortschritt lassen.
Das sollte eine Sache von Sekundenbruchteilen sein. Unwahrnehmbar schnell. Tausende Zeilen, selbst wenn die Zeilen tausende Zeichen lang sind, sind absolut gar nichts für einen Computer. Du machst sicherlich etwas furchtbar falsch. Hier sollte der Ansatz zur Verbesserung liegen.
Ich habe eine Textdatei mit über 10 000 Zeilen, aus der ich nur bestimmte Zahlen benötige.
Sicher, dass C++ hier das richtige Mittel ist? Das klingt nach einem Einzeiler für Konsolentools wie grep.
Irgendwie kommt es mir so vor, als hätte ich das schon einmal geschrieben. *such* Hier:
http://www.c-plusplus.net/forum/p2362383#2362383Zu deinem Code: Das sieht ungeheuer umständlich aus. Man liest nicht einzelne Zeichen, wenn man nicht muss. Man vergleicht nicht nach jedem Zeichen, wenn man nicht muss. Außerdem passt der Kontrollfluss deines Programms nicht zu dem, was du im anderen Thread als Aufgabe beschrieben hast, das Programm sollte nicht korrekt funktionieren. Du hast den Code abgeschrieben und verändert, ohne ihn zu verstehen, oder?
Wenn es schon C++ für diese Aufgabe sein soll, dann lies doch einfach alles in einem Rutsch ein (oder in großen Blöcken) und durchsuch die Blöcke nach den Schlüsselwörtern. Etwas anderes macht grep übrigens auch nicht, weshalb das am Ende gleich schnell sein sollte (und im Zweifelsfall ist dein Programm langsamer, da grep ziemlich flott ist und du wahrscheinlich irgendwelche Fehler machst).
-
Ja das ist richtig. Ihr habt mir hier schonmal sehr geholfen.
Ich habe jetzt aber eine Lösung für mein Problem:
// data size ifstream file1( source_file, ifstream::in | ifstream::binary ); file1.seekg(0, ios::end); int fileSize = file1.tellg(); file1.close(); cout << fileSize << endl;
Damit kann ich arbeiten
Das Programm soll nicht perfekt sein. Es muss nur funktionieren...
-
djnforce schrieb:
Das Programm soll nicht perfekt sein. Es muss nur funktionieren...
Es gibt einen Unterschied zwischen nicht-perfekt und schlecht. Du könntest mit einfacheren Mitteln in viel kürzerer Zeit ein viel besseres Ergebnis erreichen, wenn du dich nicht so verbissen an deine (abgeschriebene) Lösung klammern würdest. Ich habe irgendwie den Eindruck, dass outs Lösung aus dem anderen Thread nicht so ganz ernst gemeint war...
-
Spaßeshalber vergleich doch mal die Geschwindigkeit (Compileroptimierungen nicht vergessen!):
1. deine Lösung
2. etwas umständliche C++-Lösung von mir (die aber trotzdem besser sein könnte als das bisherige)
3. Quick&Dirty C-Lösung (inspiriert von Wutz aus anderem Thread. Vermutlich die schnellste Lösung)
4. etwas umständliche grep-Lösung(Man beachte, dass die Programme jeweils leicht unterschiedliche Ausgaben haben. Ich bin nicht 100% sicher, was die Aufgabe ist. Ich habe jeweils eine mir sinnvoll erscheinende Lösung gewählt)
Codes:
1. hast du selber
2.#include <string> #include <fstream> #include <iterator> #include <tuple> #include <cstdlib> #include <iostream> using namespace std; double parse_fs(const string &data, size_t pos) { return strtod(data.c_str() + pos, 0); } tuple<double, double> parse_coord(const string &data, size_t pos) { double x = strtod(data.c_str() + pos, 0); size_t after_comma = data.find(',', pos) + 1; double y = strtod(data.c_str() + after_comma, 0); return make_tuple(x,y); } int main() { ifstream file("test.dat"); string data(istreambuf_iterator<char>(file.rdbuf()), istreambuf_iterator<char>()); const string what_fs = "Fieldstrength : "; const string what_coord = "Coord:("; size_t fs_pos = data.find(what_fs); size_t coord_pos = data.find(what_coord); if (fs_pos != string::npos) cout << "Fieldstrength : " << parse_fs(data, fs_pos + what_fs.length()) << '\n'; if (coord_pos != string::npos) { double x, y; tie(x,y) = parse_coord(data, coord_pos + what_coord.length()); cout << "Coord x: " << x << "\nCoord y: " << y << '\n'; } }
Falls du kein C++11 hast, lass die Tupel eben weg.
3.#include <stdio.h> int main() { FILE *file = fopen("test.dat", "r"); int c; while ((c = fgetc(file)) != EOF) { double fs, x, y; if (c == 'F' && 1 == fscanf(file, "ieldstrength : %lf", &fs)) printf("Fieldstrength: %f\n", fs); if (c == 'C' && 2 == fscanf(file, "oord:(%lf,%lf", &x, &y)) printf("Coord x: %f\nCoord y: %f\n", x, y); } }
FS=`grep -o -m1 "Fieldstrength : [0-9]*" $1 | cut -d' ' -f3` XY_STRING=`grep -o -m1 "Coord:([0-9]*,[0-9]*)" $1` X=`echo $XY_STRING | cut -d'(' -f2 | cut -d',' -f1` Y=`echo $XY_STRING | cut -d',' -f2 | cut -d')' -f1` echo $X, $Y, $FS