problem!
-
also, mache gerade nen praktikum und muß dort ein programm (C++)schreiben mit dem ich telegramm dateien decodiere (Hex > Klartext(Dez)).
da ich auf dem gebiet noch nen kleiner noob bin, habe ich auch noch arge probs und hoffe auf eure hilfe.
die telegrammdateien sind so aufgebaut:K0 08:41:35,050 :12 ED FF.13 EC 89 60 67
K0 08:41:35,054 :16 E9 1E.10 09 C2 02 07
usw.zur erklärung:
K0 = sendekanal (darf 0-7 sein)< muss geprüft werden
08:41:35,050 = zeitstempel (wird so übernommen
:12 ED = empfänger (uninteressant)
FF = Auftragsart (muß ich mit einer textdatei vergleichen und den dementsprechenden klartext ausgeben)
alles nach dem punkt sind reine nutzdatenso datei öffnen habe ich. jetzt will ich die kanalnummer prüfen, aber klappt nicht wirklich.
habe bisher folgenden code:
#include <iostream> #include <fstream> #include <string> using namespace::std; int main () { string data; const char *failure; failure = "Datei nicht gefunden!"; ifstream teldat; teldat.open("H:\\My Documents\\BMR Diagnosetool\\EingangsTelegramme\\0308080841TEST.BMS"); ofstream telout; telout.open("H:\\My Documents\\BMR Diagnosetool\\AusgangsTelegramme\\0308080841TEST.txt"); if (!teldat) cout << failure << endl; int pos; while(!teldat.eof()) { teldat >> data; pos=data.find('K'); //im string nach "K" suchen telout << data.substr(0,pos); } teldat.close(); telout.close(); }
die ausgabe soll in einer separaten datei erfolgen. allerdings schreibt er auch alles rein, nur die "K0" nicht
wollte jetzt mit dem substring "K0" rausziehen, prüfen und in die ausgabedatei schreiben. mein prob ist aber das ich nicht genau weiß wie ich das prüfen soll.hatte erst diese idee:
if (data<=7) telout << data.substr(0,pos);
aber das funzt nicht wirklich.
bekomme immer folgende meldung:
test.cpp:23: no match for `std::string& <= int' operatorwas ist falsch an diesem code.
aso, den code habe ich aus eurem forum und einfach ein wenig angepasst.
ich weiß das es nicht die feine englische art ist, aber wusste nicht wie ich es sonst machen sollte.
muß auch zugeben das folgender code für mich auch nicht ganz ersichtlich ist:telout << data.substr(0,pos);
das er es in die ausgabedatei schreiben soll, ok, aber alles was dann kommt verstehe ich leider nicht wirklich
ich hoffe das ihr mir hier helfen könnt.
-
juppiefreakk schrieb:
if (data<=7) telout << data.substr(0,pos);
aber das funzt nicht wirklich.
bekomme immer folgende meldung:
test.cpp:23: no match for `std::string& <= int' operatorwas ist falsch an diesem code.
du vergleichst hier zwei Datentypen unterschiedlicher Art (für einen solchen Vergleich ist kein operator<= definiert!). Du mußt entweder data zu einem int-Wert (zB mit atoi() oder mit Hilfe stringstreams) konvertieren oder data mit dem Ascii-Code von 7 vergleichen.
Außerdem:
spare dir das .open:ifstream teldat("H:\\My Documents\\BMR Diagnosetool\\EingangsTelegramme\\0308080841TEST.BMS");
analog bei ofstream (.close kannst du bei fstreams auch weglassen;-)))
Wie genau dürfen die Eingabe daten aussehen? Prüfe deine Eingabedaten auch auf formale Fehler!
zB:short kanal, formalErrorCode=0, logicalErrorCode=0; while( !teldat.eof() ){ teldat >> kanal; if( teldat.fail() ){ errorCode=1; } else{ if( kanal>7 ){ errorCode= 2;//ist eigentlich ein logischer Fehler! schöner sind separate Fehlercodes } else....... } }
-
thx freshman, werde mir alles nochmal in ruhe zu gemüte führen und schauen was dann draus wird.
werde bestimmt demnächst noch weitere fragen dazu haben, da ich dann noch bitoperationen habe und die werden bestimmt hackelig
-
@juppiefreakk: u're welcome!
aber bitte sprechende Fragentitel und nicht zB "problem!"
-
oki, werde ich machen
-
sorry for doppelpost!
sag mal, hierbeishort kanal, formalErrorCode=0, logicalErrorCode=0; while( !teldat.eof() ){ teldat >> kanal; if( teldat.fail() ){ errorCode=1; } else{ if( kanal>7 ){ errorCode= 2;//ist eigentlich ein logischer Fehler! schöner sind separate Fehlercodes } else....... } }
errorCode muß ich das noch definieren, bzw den inhalt oder habe ich da was falsch verstanden?
-
sorry,
errorCode soll auch nur eine ganzzahl-Vari sein wie zB formalErrorCode
ich mache es immer so, daß ich eine Variable short formalErrorCode und eine logicalErrorCode definiere (0:=kein Fehler). Dann prüfe ich zuerst auf formale Fehler, dann auf inhaltliche (outsourcing nicht vergessen). Bei dem Bsp habe ich nur errorCode benutzt, weil ich keine Unterscheidung zwischen formaler oder inhaltlicher Fehlerart gemacht habe. Aber Du hast schon recht müßte natürlichshort kanal, errorCode=0; while( !teldat.eof() ){ teldat >> kanal; if( teldat.fail() ){ errorCode=1; } else{ if( kanal>7 ){ errorCode= 2;//
sein
-
sache mal (ich glaube ich bin recht nervig
)
wäre es nicht besser das mit einer switch case schleife zu lösen, ich glaube das sieht besser aus?ok, muß ich nicht fragen, kann es ja auch alleine abändern. aber vielleicht gibbet da auch noch was wichtiges zu beachten
-
wie willst du denn dabei ein switch gebrauchen?
mein Vorschlag war nur so gemeint:
[begin_megaPseudoCode]
//in der Eingabe:
solange datei nicht zu ende
//Zeilenweise bzw. Abschnittsweise
checke Variable, die als erstes erwartet wird
wenn erste Vari okay
checke Variable, die als zweites erwartet wird
wenn zweites Vari okay
....
ansonsten jeweils Fehlercode setzen//in der Ausgabe:
wenn kein Fehler
normale Ausgabe
wenn Fehler
evaluierte Fehlermeldung/-behandlung
[end_megaPseudoCode]
-
so, habe das prob gelöst
und funzt auch wunderbar.
#include <iostream> #include <fstream> #include <string> #include <sstream> const char * const pFILENAME1 = "H:\\My Documents\\BMR Diagnosetool\\EingangsTelegramme\\0308080841.BMS"; // Telegrammdatei const char * const pFILENAME2 = "H:\\My Documents\\BMR Diagnosetool\\AusgangsTelegramme\\0308080841.txt"; // Ausgabedatei const char * const pFILENAME3 = "H:\\My Documents\\BMR Diagnosetool\\Fehlerprotokoll\\0308080841FAIL.txt"; // Fehlerprotokolldateidatei const char * const pFILENAME4 = "H:\\My Documents\\BMR Diagnosetool\\auftrag.txt"; //Auftragsartendatei using namespace::std; // Namensraum std einbinden int main() //Hauptfunktion { ifstream inFile; // Telegrammdatei öffnen inFile.open(pFILENAME1); if (!inFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME1 << " konnte nicht gefunden werden." << endl; exit (1); } ofstream outFile; // Ausgabedatei öffnen bzw anlegen outFile.open(pFILENAME2); if (!outFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME2 << "ist nicht vorhanden." << endl; exit (1); } ofstream failFile; // Fehlerdatei öffnen bzw anlegen failFile.open(pFILENAME3); if (!failFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME3 << "ist nicht vorhanden." << endl; exit (1); } ifstream auftragFile; // Auftragsartendatei öffnen auftragFile.open(pFILENAME4); if (!auftragFile) // Prüfen ob datei vorhanden { cout << "Datei " << pFILENAME4 << "ist nicht vorhanden." << endl; } do // Komplette Datei bearbeiten { string line; // Stringvariable Zeile string kanal; // Stringvariable Kanalnummer istringstream iskanal; // Konvertierungsstream getline(inFile, line); // Zeile einlesen if (inFile.eof()) // Bei erreichen des Dateiendes Rest überspringen (!!!) continue; iskanal.str(line); // Eingelesene Zeile dem Konvertierungsstream zuweisen getline(iskanal, kanal, '.'); // Daten aus der Zeile extrahieren if( kanal[1] >= '0' && kanal[1] <= '7') // Prüfung ob Kanalnummer zwischen 0 und 7 liegt { outFile << line << endl; // Extrahierte Daten in Ausgabedatei schreiben } else { failFile << "Fehler! Falsche Kanalnummer." << endl; // Protokoll in Fehlerdatei schreiben } } while (!inFile.eof()); inFile.close(); // Datei wieder schliessen }
jetzt werde ich mal versuchen die auftragsarten auszufiltern und mit den daten aus der auftrag.txt vergleichen
-
so, lebe doch noch, habe aber ein neues prob.
habe immo an dateien:
main.cpp = hauptfunktion.#include <iostream> #include <fstream> #include <string> #include <sstream> using namespace::std; // Namensraum std einbinden #include "dateien.h" // <<<< Headerdatei hinzugefuegt #include "auftrag.h" // <<<< Headerdatei hinzugefügt int main() //Hauptfunktion (Nebenfunktion) { // <<< Definition der Streams hier, da sie in main() weiterverwendet werden ifstream inFile; // Telegrammdatei öffnen ofstream outFile; // Ausgabedatei öffnen bzw anlegen ofstream failFile; // Fehlerdatei öffnen bzw anlegen ifstream auftragFile; // Auftragsartendatei öffnen if (!dateien(inFile, outFile, failFile, auftragFile)) { cout << "Fehler beim Oeffnen der Dateien\nProgramm wird beendet!"; exit(1); } auftragsart(); do // Komplette Datei bearbeiten { string line; // Stringvariable Zeile getline(inFile, line); // Zeile einlesen string telekopf = line.substr (0, 28); // Substringvariable Telegrammkopf (Kanalnr. -> Auftragsart) if (inFile.eof()) // Bei erreichen des Dateiendes Rest überspringen (!!!) continue; if( telekopf[0] >= '0' && telekopf[1] <= '7') // Prüfung ob Kanalnummer zwischen 0 und 7 liegt { outFile << telekopf << endl; // Extrahierte Daten in Ausgabedatei schreiben if( line[28] == auftragsnr[0] && line[29] ==auftragsnr[1]) { if ( auftragsname == '0') { failFile << "Für diese Auftragsart liegt keine Definition vor." << endl; } outFile << telekopf << auftragsname << endl; } //outFile << telekopf << endl; // Extrahierte Daten in Ausgabedatei schreiben } else { failFile << "Fehler! Falsche Kanalnummer." << line << endl; // Protokoll in Fehlerdatei schreiben } } while (!inFile.eof()); inFile.close(); // Datei wieder schliessen }
auftrag.cpp:
#include <iostream> #include <fstream> #include <string> #include <sstream> using namespace::std; // Namensraum std einbinden #include "dateien.h" // <<<< hinzugefuegt #include "auftrag.h" int auftragsart(string& auftrag, string& auftragsnr, string& auftragsname) //Hauptfunktion { ifstream inFile; // Telegrammdatei öffnen ofstream outFile; // Ausgabedatei öffnen bzw anlegen ofstream failFile; // Fehlerdatei öffnen bzw anlegen ifstream auftragFile; // Auftragsartendatei öffnen if (!dateien(inFile, outFile, failFile, auftragFile)) { cout << "Fehler beim Oeffnen der Dateien\nProgramm wird beendet!"; exit(1); } do // Komplette Datei bearbeiten { string auftrag; // Stringvariable Zeile getline(auftragFile, auftrag); // Zeilen einlesen string auftragsnr = auftrag.substr (0, 2); // Substringvariable Auftragsnummer string auftragsname = auftrag.substr(7, auftrag.length() -1); // Substringvariable Auftragsname (bis Ende des Namens) if(auftragFile.eof()) continue; //cout << auftragsnr << endl; } while (!auftragFile.eof()); auftragFile.close(); // Datei wieder schliessen return 0; }
dateien.cpp:
#include <iostream> #include <sstream> #include <string> using namespace::std; // Namensraum std einbinden // <<<< wenn schon using namespace, dann hier definieren da // <<<< Headerdatei die Streams verwendet #include "dateien.h" // <<< eigene Header-Datei einbinden const char * const pFILENAME1 = "H:\\My Documents\\BMR Diagnosetool\\EingangsTelegramme\\0308080841.BMS"; // Telegrammdatei const char * const pFILENAME2 = "H:\\My Documents\\BMR Diagnosetool\\AusgangsTelegramme\\0308080841.txt"; // Ausgabedatei const char * const pFILENAME3 = "H:\\My Documents\\BMR Diagnosetool\\Fehlerprotokoll\\0308080841FAIL.txt"; // Fehlerprotokolldateidatei const char * const pFILENAME4 = "H:\\My Documents\\BMR Diagnosetool\\auftrag.txt"; //Auftragsartendatei // <<< umbenannt nach dateien() // <<< Es darf innerhalb eines C++ Programms nur // <<< nur ein main() geben!!! main() ist der Einsprung // <<< ins Programm. bool dateien(ifstream& inFile, ofstream& outFile, ofstream& failFile, ifstream& auftragFile) { inFile.open(pFILENAME1); if (!inFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME1 << " konnte nicht gefunden werden." << endl; return false; } outFile.open(pFILENAME2); if (!outFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME2 << "ist nicht vorhanden." << endl; return false; } failFile.open(pFILENAME3); if (!failFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME3 << "ist nicht vorhanden." << endl; return false; } auftragFile.open(pFILENAME4); if (!auftragFile) // Prüfen ob Datei vorhanden { cout << "Datei " << pFILENAME4 << "ist nicht vorhanden." << endl; return false; } return true; }
dateien.h:
#include <fstream> bool dateien(ifstream& inFile, ofstream& outFile, ofstream& failFile, ifstream& auftragFile);
auftrag.h:
#include <string> int auftragsart(string& auftrag, string& auftragsnr, string& auftragsname);
und zu guter letzt mein makefile:
# Liste der Source-Dateien SOURCES = auftrag.cpp dateien.cpp main.cpp # Name der ausfuehrbaren Datei TARGET = main.exe # ==== Ab hier sind in der Regel keine Anpassungen notwendig === # Source- und Object-Verzeichnis SDIR = . ODIR = . .PHONY: all clean rebuild checkdir # Suchpfad fuer .o Dateien auf Object-Verzeichnis # Wird benoetigt, da Datei mit den Abhaengigkeiten (dfile) keine # Pfade enthaelt vpath %.o $(ODIR) # Pfad fuer Konsolen-Befehle # Konsolen-Befehle verwenden Backslash anstelle von Slash # Wird fuer clean und checkdir benoetigt CODIR = $(subst /,\,$(ODIR)) # Liste der Objects, wird aus Source-Files generiert OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))) # Verzeichnis vor Source- und Objects stellen ROBJ = $(addprefix $(ODIR)/,$(OBJS)) RSRC = $(addprefix $(SDIR)/,$(SOURCES)) # Compiler-Flags setzen CXXFLAGS = -c -Wall -pedantic # Im Debugfall Debug-Output erzeugen und Symbole aus TARGET nicht entfernen # ansonsten Optimierung einschalten und Symbole aus TARGET entfernen ifdef DEBUG CXXFLAGS += -ggdb STRIP= else CXXFLAGS += -O3 STRIP=strip $(ODIR)/$(TARGET) endif # Default-Ziel all: checkdir depends $(ODIR)/$(TARGET) # Abhaengigkeit des EXE-Datei und Regel $(ODIR)/$(TARGET): $(OBJS) g++ $(ROBJ) -o $@ $(STRIP) # Regel wie .o aus .cpp erzeugt wird %.o:%.cpp g++ $(CXXFLAGS) $(SDIR)/$< -o $(ODIR)/$@ # Alles wieder aufraeumen clean: -@del $(CODIR)\*.o -@del $(CODIR)\*.exe -@del dfile # Alles neu bauen rebuild: clean all # Pruefen ob Verzeichnis fuer .o-Dateien exisitiert checkdir: @if not exist $(CODIR) mkdir $(CODIR) # Datei mit den Abhaenigkeiten cpp->h erzeugen depends: $(SOURCES) g++ -MM $(SOURCES) >dfile # Datei mit den Abhaengigkeiten einbinden -include dfile
ansich klappt das alles ja wunderbar, nur beim compilieren meckert er immer rum das in der main.cpp auftragsnr und auftragsname nicht definiert sind. ich habe echt null plan warum er das nicht vernünftig einbindet. wäre nett wenn ich dabei nochmal hilfe haben könnte.
thx schonma