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 nutzdaten

    so 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' operator

    was 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' operator

    was 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, hierbei

    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.......
        }
    }
    

    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ürlich

    short 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


Anmelden zum Antworten