Textdatei auslesen und interpretieren
-
Hallo zusammen!
Für ein Projekt muss ich eine Oberfläche erstellen die eine .txt- Datei auslesen kann, die Werte interpretiert und über die Rs232- Schnittstelle weiter versendet.
Die Txt.Datei sieht ungefähr so aus:
Random Inhalt
.STIMULUS binär STIM (8,11111111)
+ +0s 11100000
+ 1200ms 10101011
+ 1400ms 11001101
+ 1600ms 11100010
Random inhaltDie Auszulesenden Daten sind die Zeiten, und die Pegel dazugehörigen Pegel( also der 8 Bit Binärcode) dahinter. Die zeiten sollen später je nach Endung in Nanosekunden umgewandelt werden...
Nun meine Fragen:
1. Mit welcher Funktion lese ich die Werte am Besten aus?
2. Schreibe ich die Daten dann am Besten in ein oder 2 Arrys?Ich hoffe ich konnte mein Problem deutlich machen.
Wär toll wenn mir da jemand helfen könnte.
Gruß
Michael
-
Micki E. schrieb:
Die Auszulesenden Daten sind die Zeiten, und die Pegel dazugehörigen Pegel( also der 8 Bit Binärcode) dahinter. Die zeiten sollen später je nach Endung in Nanosekunden umgewandelt werden...
Nun meine Fragen:
1. Mit welcher Funktion lese ich die Werte am Besten aus?
2. Schreibe ich die Daten dann am Besten in ein oder 2 Arrys?Hallo Michael,
zu 1.) in C++ am besten mit den Methoden von std::istream bzw. std::ifstream.
und zu 2.) am besten in ein Array mit Instanzen einer Struktur/Klasse, die die Zeiten und die Pegelwerte enthält. Alles andere würde ich als Designfehler ansehen. Also z.B.:struct Pegel { int zeit_ns_; // Zeit in [nanosekunden] unsigned char val_; // Wert des Pegels };
Dann brauchst Du noch eine Funktion zum Einlesen:
std::istream& operator>>( std::istream& in, Pegel& pegel );
Sieht man nur auf die benötigten Werte, so muss die Zeit mit Einheit und der Wert im Binärcode eingelesen werden. Die Zeit wiederum besteht aus einem Wert und der Einheit. Dazu baue man sich einen sogenannten Manipulator
// -- Einlesen eines Zeitwertes mit Einheit; z.B.: 450ms struct zeit_in_ns // Manipulator zum Einlesen einer Zeit mit Einheit { explicit zeit_in_ns( int& ns ) : val_( ns ) {} int& val_; // nano Sekunden }; namespace unit_detail { struct Unit // Typ für eine Einheit mit Multiplikator { bool operator==( const std::string& s ) const { return s == name_; } const char* name_; int factor_; }; } std::istream& operator>>( std::istream& in, zeit_in_ns t ) { int val; std::string einheit; if( in >> val >> einheit ) { static const unit_detail::Unit einheiten[] = { {"s", 1000000000 }, {"ms", 1000000 }, {"us", 1000}, {"ns", 1} }; const unit_detail::Unit* i = std::find( einheiten, einheiten + sizeof(einheiten)/sizeof(*einheiten), einheit ); if( i != einheiten + sizeof(einheiten)/sizeof(*einheiten) ) t.val_ = val * i->factor_; // ggf. auf int-overflow prüfen! else in.setstate( std::ios_base::failbit ); } return in; }
Die Anwendung sähe so aus:
int zeit; if( cin >> zeit_in_ns( zeit ) ) cout << zeit << "ns" << endl;
mit einer Eingabe von 20us würde dieses Programmschnipsel 20000ns ausgeben.
Den binären Wert für den Pegel liest man am einfachsten als bitset ein. Dann hat man alles bei einander um die Funktion für das Einlesen eines Pegelwerts inklusive der Zeit zu implementieren:
// -- Pegel einlesen std::istream& operator>>( std::istream& in, Pegel& pegel ) { std::bitset<8> bs; if( in >> zeit_in_ns( pegel.zeit_ns_ ) >> bs ) pegel.val_ = static_cast< unsigned char >( bs.to_ulong() ); return in; }
Ich unterstelle mal, dass das '+'-Zeichen nur am Anfang einer Zeile mit Pegel-Eintrag vorkommt. Dann kann man mit der Methode ignore einfach alles andere bis zum '+' über lesen.
Also:int main() { using namespace std; vector< Pegel > pegel; ifstream in("input.txt"); if( !in.is_open() ) { cerr << "Fehler beim Oeffnen" << endl; return -2; } for( Pegel pgl; in.ignore( numeric_limits< streamsize >::max(), '+' ) >> pgl; ) pegel.push_back( pgl ); if( in.eof() ) cout << pegel.size() << " Pegel-Eintraege gelesen" << endl; return 0; }
An includes brauchst Du noch:
#include <iostream> #include <limits> #include <fstream> #include <string> #include <bitset> #include <vector>
nanosekunden ist eine sehr kleine Einheit. Wenn Du int als Typ verwendest (Member Pegel::zeit_ns_) kannst Du damit maximal 2,14s darstellen (4 Byte int vorausgesetzt). Höhere Werte würden im manipulator zeit_in_ns zu einem overflow führen.
Gruß
Werner
-
Ui Dann mal vielen dank für die Vorschläge. ich probiers mal aus und meld dann wieder
Gruß Michael