Nur bestimmte Zahlen aus Textdatei auslesen
-
komplizierte Datei
Hier mal eine C++ Lösung:
#include <fstream> #include <string> using namespace std; int main() { ifstream file( "test.txt" ); if( !file.is_open() ) // Konnte die Datei geöffnet werden? return -1; ofstream new_file( "neu.txt" ); // In dieser Datei wollen wir die Zahlen abspeichern. new_file.setf(ios::fixed); // Keine wissenschaftliche Ausgabe. const string what = "Coord:("; // Das suchen wir. string str; // Brauchen wir, um zu testen, wann die beiden Zahlen kommen. for(char c; file.get(c);) // Pro Schleifendurchgang lesen wir 1 Zeichen aus der Datei. { str += c; // Das gelesene Zeichen hängen wir an unseren string an. if( str == what ) // Wenn im string nun "Coord:(" steht, kommen nun die beiden Zahlen. { double x; file >> x; // Wir lesen die erste Zahl. file.ignore( 1 ); // Das Komma interessiert uns nicht, darum ignorieren wir es. double y; file >> y; // Wir lesen die zweite Zahl. if( file ) // Bevor wir die beiden Zahlen in die neue Datei schreiben, müssen wir vorher natürlich prüfen, ob das Einlesen der Zahlen überhaupt erfolgreich war. { new_file << x << ',' << y << '\n'; // Einlesen war erfolgreich. Beide Zahlen abspeichern. } str.clear(); // Wir haben zwei Coords gefunden. Nun fängt das Ganze wieder von vorne an. } else if( str.length() == what.length() ) { // Wir wollen max. 7 Zeichen im string. // Für den nächsten Schleifendruchgang löschen wir darum das erste Zeichen des strings, damit es nicht 8 Zeichen werden. str.erase( 0, 1 ); } } // return 0; // ==> Wird in der main (nur in der main) automatisch gemacht. MUsst du also nicht extra hinschreiben. }
-
Wow, hast du das jetzt in den letzten 30 min gemacht? ich bin begeistert. Werde es nach dem Mittag gleich testen und mich wieder melden...
-
djnforce schrieb:
Wow, hast du das jetzt in den letzten 30 min gemacht? ich bin begeistert. Werde es nach dem Mittag gleich testen und mich wieder melden...
Ne, so lange hab ich jetzt nicht gebraucht. Naja der Ansatz ist ziemlich einfach. Zeichen für Zeichen lesen. Zeichen hinten an string anhängen. Zeichen ganz vorne löschen. Dann zwei Zahlen auslesen und abspeichern.
Naja und das Kommentieren dauert immer am Längsten.
-
Solche Sachen gehen auch in purem C und meist sehr viel kürzer:
int main() { unsigned long a,b; FILE *f=fopen("test.txt","r"); int c; while( (c=fgetc(f))!=EOF ) if( c=='C' && 2==fscanf(f,"oord:(%lu,%lu",&a,&b) ) printf("%lu,%lu",a,b); fclose(f); return 0; }
-
Hallo out,
vielen vielen Dank. es funktioniert wie es soll. Nur noch zwei Fragen: Wie kann ich dass Komma nach den ersten beiden Ziffern einfügen und wie kann ich die Anzahl der Ziffern in x und y variieren?
Also: 33.73055528,51.5242529
Vielen Dank nochmals
-
Welche mathematische Operation fällt dir denn ein, mit der man sowohl von 5763723838 auf 57.63723838 kommt, als auch von 2126388 auf 21.26388? Tipp: Die Antwort beinhaltet eine der folgenden Operationen: /*-+
-
natürlich
-
Hallo liebe Community,
ich habe mal wieder ein Problem. Eure Hilfe von gestern war echt super und hat mir sehr geholfen. Jetzt habe ich aber eine neue Textdatei in welche neben den Koordinaten auch Feldstärken stehen. Aus dieser Datei soll nun eine neue Datei generiert werden, welche folgenden Inhalt haben soll x-Wert, y-Wert, Value, wobei Value die Feldstärke sein soll. Ich habe euren Code von gestern nun versucht zu erweitern und bekomme es einfach nicht hin. Was mache ich falsch??
#include <fstream> #include <string> #include <iostream> using namespace std; int main() { ifstream file( "test.txt" ); if( !file.is_open() ) // Konnte die Datei geöffnet werden? return -1; ofstream new_file( "neu.txt" ); // In dieser Datei wollen wir die Zahlen abspeichern. new_file.setf(ios::fixed); // Keine wissenschaftliche Ausgabe. const string what = "Coord:("; // Das suchen wir. const string what2 = "Fieldstrength : "; // Das suchen wir auch. string str; // Brauchen wir, um zu testen, wann die beiden Zahlen kommen. string str2; // brauchen wir, um zu testen, wann die Feldstärke kommt. for(char c; file.get(c);) // Pro Schleifendurchgang lesen wir 1 Zeichen aus der Datei. { str += c; // Das gelesene Zeichen hängen wir an unseren string an. //cout << str2 << endl; //system("pause"); if( str == what ) // Wenn im string nun "Coord:(" steht, kommen nun die beiden Zahlen. { double x; double value = 1; file >> x; // Wir lesen die erste Zahl. file.ignore( 1 ); // Das Komma interessiert uns nicht, darum ignorieren wir es. double y; file >> y; // Wir lesen die zweite Zahl. if( file ) // Bevor wir die beiden Zahlen in die neue Datei schreiben, müssen wir vorher natürlich prüfen, ob das Einlesen der Zahlen überhaupt erfolgreich war. { new_file << x/100000000 << ',' << y/10000000 << ',' << value << '\n'; // Einlesen war erfolgreich. Beide Zahlen abspeichern. } str.clear(); // Wir haben zwei Coords gefunden. Nun fängt das Ganze wieder von vorne an. } else if( str.length() == what.length()) { // Wir wollen max. 7 Zeichen im string. // Für den nächsten Schleifendruchgang löschen wir darum das erste Zeichen des strings, damit es nicht 8 Zeichen werden. str.erase( 0, 1 ); } } // ab hier neu for(char c; file.get(c);) // Pro Schleifendurchgang lesen wir 1 Zeichen aus der Datei. { str2 += c; // Das gelesene Zeichen hängen wir an unseren string an. if( str2 == what2 ) // Wenn im string nun "Coord:(" steht, kommen nun die beiden Zahlen. { double value; // Feldstärke file >> value; // Feldstärke einlesen if( file ) { new_file << value << '\n'; // Einlesen war erfolgreich. Feldstärke abspeichern. } str2.clear(); // Nun fängt das Ganze wieder von vorne an. } else if( str2.length() == what2.length()) { // Wir wollen max. 7 Zeichen im string. // Für den nächsten Schleifendruchgang löschen wir darum das erste Zeichen des strings, damit es nicht 8 Zeichen werden. str2.erase( 0, 1 ); } } // return 0; // ==> Wird in der main (nur in der main) automatisch gemacht. MUsst du also nicht extra hinschreiben. }
Hier auch noch ein Auszug aus der Textdatei:
=> ATStationTmcInfo : enATStationTmcInfo_Station_is_TMC_station (0x02)
=> Fieldstrength : 56 dB/uV
=> u8Quality : 00
=> Band : enBand_FM (0x00)
=> ActivePresetList : 0f20
=> PresetAutocompare : 0000
=> StationListAutocompare: 0000
=> ATStationInfo : 06
[tun_DrvAdrIf.hpp(1792)]
proxyfile@cardTrace Class : TUN_TRACE_CLASS_DRVADRIF Trace Level : TR_LEVEL_USER_1[STATE_TRANSITION]
proxyfile@card(core2)fc_tmctuner_US1_ETG_TUN_TRACE_CLASS_DRVADRIF: tun_DrvAdrIf::vFreeRxDataBuffer() -> release Rx SSI buffer [tun_DrvAdrIf.cpp(541)]
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_DEAD_RECKONING_POSITION->STATUS) State: VALID, Time: 37278, Posix: 37s+628ms, Pos: (-921911768,515242529) (Err:406,163,1), Head: 258 (Err:5098), Turnrate: 1 (Err:9), Speed:0 (Err:270), Accel: 0 (Err:249), Height: 0 (Err:2), Sensors: prov:15, det:6, used:6, cal:0
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_POSITION->STATUS) WGS84: (-921911785,515242200), Reliab: 0x001E, Speed: 0 cm/s, Head: 0xFE, ON_ROAD, Time: 37.628, Inclination: 0, Acceleration: 0 cm/s^2, Height: (0,) m
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_EXTRAPOLATED_POSITIONS->STATUS) Dataset:235575863 RelID:1 Rel:80 Time:38,698 Int:40 NumPts:50: Coord:(3373055528,515242529) Head:16456 Angl:16456 Speed:0 7F 54 00 00 78 24 1B 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 81 24 32 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 C0 24 42 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 FF 24 51 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 3E 25 5F 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 7C 25 6D 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 12 55 00 00 BA 25 7A 01 00 55 00 00 00 00 28 BE
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_DEAD_RECKONING_POSITION->STATUS) State: VALID, Time: 38278, Posix: 38s+628ms, Pos: (-921911768,515242529) (Err:406,164,1), Head: 231 (Err:5098), Turnrate: 0 (Err:0), Speed:0 (Err:0), Accel: 0 (Err:0), Height: 0 (Err:2), Sensors: prov:15, det:6, used:6, cal:0
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_POSITION->STATUS) WGS84: (-921911785,515242200), Reliab: 0x001E, Speed: 0 cm/s, Head: 0xFE, ON_ROAD, Time: 38.628, Inclination: 0, Acceleration: 0 cm/s^2, Height: (0,) m
proxyfile@cardTrace Class : TR_ENAVI_RECV_DATA Trace Level : TR_LEVEL_SYSTEM[ERROR]
proxyfile@card(core0)ENAVI_RX: (POS_EXTRAPOLATED_POSITIONS->STATUS) Dataset:235575863 RelID:1 Rel:80 Time:39,708 Int:40 NumPts:50: Coord:(3373055528,515242529) Head:16456 Angl:16456 Speed:0 12 55 00 00 81 24 32 01 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 81 24 38 00 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 C0 24 4F 00 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 FF 24 61 00 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 3E 25 70 00 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 7C 25 7D 00 00 55 00 00 00 00 28 BE 0C C9 21 FA B5 1E 48 40 48 40 00 00 16 55 00 00 BA 25 89 00 00 55 00 00 00 00 28 BE
proxyfile@cardTrace Class : TUN_TRACE_CLASS_DRVADRIF Trace Level : TR_LEVEL_USER_2[EVENT]Vielen Dank schonmal und viele Grüße...
-
Was ist denn das Problem?
-
Nichts gegen C++, aber das kann man ja nicht mit ansehen, wie du solch einen Aufwand für solch eine triviale Aufgabe betreibst. Hier, fünf Zeilen Shellscript machen alles, was du willst:
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
Kurz, (relativ) einfach, erweiterbar. Jemand, der sich besser mit Regex auskennt kann sicherlich auch noch zaubern, dass man gleich den gewünschten Wert erhält, ohne die anschließende cut-Orgie. Aber auch mit meinen Laienkenntnissen ist dies doch schon sehr viel besser als das was du derzeit versuchst.
Diese Version nutzt Unix-Kommandozeilentools. Gibt sicher auch vergleichbar mächtiges für Windows, falls nötig. Zur Not gibt es diese Tools natürlich auch alle direkt für Windows.
-
So wie der Code oben abgebildet ist, wird garnicht in die zweite for-Schleife gegangen. Die Koordinaten werden mithilfe der ersten for-Schleife ausgelesen und sauber in die neue Textdatei geschrieben (Mit einem fiktiven Value Wert von 1).
Ich glaub ich seh den Wald vor Bäumen nicht. So schwer kann das doch nicht sein oder?
-
Hier, fünf Zeilen Shellscript machen alles, was du willst
Ich habe jetzt aber mit c++ begonnen und würde es auch gern damit beenden. Viel fehlt ja nichtmehr. Ausserdem erhoffe ich mir dadurch Lerneffekte für zukünftige Projekte.
-
djnforce schrieb:
Hier, fünf Zeilen Shellscript machen alles, was du willst
Ich habe jetzt aber mit c++ begonnen und würde es auch gern damit beenden. Viel fehlt ja nichtmehr. Ausserdem erhoffe ich mir dadurch Lerneffekte für zukünftige Projekte.
Mir fällt keine gute Lösung ein.
Da musst do wohl auf getline + stringstream zerhacke zurückgreifen.
-
Ich wähnte mich schon am Ziel, als ich las, dass man mit ignore() auch alles ignorieren kann bis zu einem definierten Character. Also bis "Fieldstrength" erscheint. Aber das geht wohl nur mit einem Zeichen und nicht mit einem ganzen Wort. Hab ich das richtig verstanden?
-
djnforce schrieb:
Ich wähnte mich schon am Ziel, als ich las, dass man mit ignore() auch alles ignorieren kann bis zu einem definierten Character. Also bis "Fieldstrength" erscheint. Aber das geht wohl nur mit einem Zeichen und nicht mit einem ganzen Wort. Hab ich das richtig verstanden?
Korrekt. Aber als Lösungsstrategie habe ich einen besseren Vorschlag: Klammer dich nicht zu sehr an deinem Format fest. Schreib lieber Funktionen, die nach bestimmten Mustern suchen und dir dann dazu Werte ausspucken. Meistens ist es einfacher, solch klar definierten Funktionen zu schreiben und das Ergebnis ist auch viel besser anpassbar, wenn sich später mal was ändert.