Datendatei aufsplitten, konvertieren und Einzelteilen speichern



  • Nimm lieber fopen wie es in dem "Script" steht. Nur dass du nicht "r+b" nimmst, was bedeutet dass du die Datei ließt, aber auch schreiben kannst, und zwar binär, sondern "wb" für schreiben, binär (Vorsicht, eine Datei mit "wb" öffnen löscht ihren Inhalt!!!) oder wenn du es brauchst "w+b" zum binären schreiben mit der Möglichkeit zu lesen.
    Wenn du eine Datei mit "w"/"wb"/"w+"/"wb+" öffnest und sie existiert nicht, dann wird sie erstellt.
    Es gibt dann noch "a" für append=anhängen, da wird die Datei zum schreiben geöffnet aber nicht gelöscht, stattdessen wird zu Ende der Datei gesprungen.
    Zum schreiben nimmst du dann fwrite, hat dieselbe Syntax wie fread.



  • Hallo Zusammen!

    Ich bastel immer noch an dem Projekt rum, bin aber für meine Verhältnisse mit dem Ergebnis schon weitgehend zufrieden. Im Moment verzweifel ich an 3 Dingen die ich noch gerne implementieren möchte.

    1. Ich möchte das Programm über drag&drop nutzen können und den Dateinamen dabei behalten und auch für die Ausgabe der Textdatei nutzen. Drag&drop geht, ich muss aber den Namen definieren bzw. die Datei dann immer umbenennen. Ich hab viel versucht und auch gegoogled, crashe aber immer nur wenn ich was anderes versuche.

    2. Ich würde gerne einen Teil der Datencontainer vor der Ausgabe verknüpfen. Z.B. Container 1 und 2 oder 1 und 3:

    Container 1 schrieb:

    berlin
    duesseldorf
    bochum
    muenchen
    frankfurt
    ulm
    koeln

    Container 2 schrieb:

    689.084961;6
    728.915039;6
    -370.133331;6
    -339.866638;6
    156.000000;6
    174.000000;6
    1188.791016;3
    1239.155029;3
    1952.000000;3
    2012.822754;3
    -10.641739;3
    30.409887;3

    Als Ergebnis möchte ich

    Container 2 schrieb:

    689.084961;koeln
    728.915039;koeln
    -370.133331;koeln
    -339.866638;koeln
    156.000000;koeln
    174.000000;koeln
    1188.791016;muenchen
    1239.155029;muenchen
    1952.000000;muenchen
    2012.822754;muenchen
    -10.641739;muenchen
    30.409887;muenchen

    Geht das überhaupt mit der aktuelle Script-Lösung (s. unten)? Bisher hab ich mir die Zähne ausgebissen und denke selber das geht nicht so wie ich das Einlesen aufgebaut habe. Die Datei die ich erzeuge hat dagegen eine Datensatznummerierung die ich verwenden könnte wenn ich ein zweites Programm erstellen würde und dort dann die beiden Container als 2 CSV-Dateien kombiniere. Wäre das die bessere Lösung?

    3. Das Einlesen des 2ten Datencontainers ist etwas fehlerhaft. Ich lese die ersten Daten über Struct als FLOAT ein, habe aber ein Mischmasch aus Floatzahlen und einer einfachen Nummerierung (Diese verweist auf Daten aus einem anderen Container der hier nicht enthalten ist). Kann float und int in der selben Datenspalte trotz Struct unterscheiden und entsprechend richtig ausgeben?

    Hier der Quellcode den ich im Moment verwende:

    //QDATDecrypter.h
    
    #ifndef QDATDECRYPTER_H
    #define QDATDECRYPTER_H
    
    #pragma pack(push, QDATDECRYPTER_H)
    #include <vector>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    #pragma pack(push, QDATDECRYPTER_H)
    #include <string>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    struct TContainer
    {
    	int					mLength;			    // Länge des Datencontainers  
    	int					mOffset;			    // Offset - Startposition des Containers  
    };
    struct THeader
    {
    	char				mDateikennung[4];	    //  Die Dateikennung ist immer "QDAT"  
    	int					mVersion;  			    //	Versionsnummer, 0x09  
    	TContainer				mContainers[3];		        //	Containerverzeichnis, 3 Container gesamt
    };
    struct TStadt
    {
    	char				mName[64];			    // Stadt  
    	unsigned char		mData1[4];			    // erst mal ignoriert um die Datenanzahl klein zu halten, alles in Quelldatei auf 00 gesetzt
    	unsigned char		mData2[4];			    // erst mal ignoriert um die Datenanzahl klein zu halten, alles in Quelldatei auf 00 gesetzt
    };
    struct TCoordinate
    {
    	float				mData3Index;		    // Data3-Index  
    	int					mStadtIndex;		    // Stadtindex  
    };
    struct TInfo
    {
    	short				mNbData3;		        // Anzahl zusammengehöriger Data3-Werte, die ersten 6 sind immer floatwerte, 
    // wenn größer 6 sind die folgenden Werte eine Nummerierung die auf Werte in DATA4 verweist 
    // (nicht hier enthalten da Datei zur Übersicht gekürzt)  
    	short				mStadtIndex;		    // Stadtindex  
    };
    
    struct TMapQDat
    {
    	THeader					         mHeader;		  
    	std::vector<TStadt>	   mStaedte;		 
    	std::vector<TCoordinate>	 mCoordinates;	  
    	std::vector<TInfo>		   mInfos;		 
    };
    // Konstante der Dateikennung
    const std::string			cDateikennung	= "QDAT";
    
    // Konstante der Dateiversion							
    const int					cVersion		= 0x09;
    
    //Konstanten zur Identifizierung der einzelen Container							
    const int					cStadtContainer	  = 0x00; 
    const int					cCoordinateContainer	= 0x01; // Coordinates   
    const int					cInfoContainer		  = 0x02; // Infos  
    
    void debugInformations(const TMapQDat& pMap, FILE* pFile);
    
    bool readMap(const std::string& pFilename, TMapQDat& pMap);
    
    void freeMap(TMapQDat& pMap);
    
    bool isValid(const TMapQDat& pMap);
    
    #endif
    
    //QDATDecrypter.cpp
    
    #include "QDATDecrypter.h"
    #pragma pack(push, QDATDECRYPTER_H)
    #include <cstdio>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    // Prüfen des Dateiheaders
    bool isValid(const TMapQDat& pMap)
    {
    	// 1. Prüfung der Dateikennung
    	if
    		(strncmp(pMap.mHeader.mDateikennung, cDateikennung.c_str(), 4) != 0)
    	{
    		return false;
    	}
    
    	// 2. Prüfung der Versionsnummer
    	if
    		(pMap.mHeader.mVersion != cVersion)
    	{
    		return false;
    	}
    
    	return true;
    }
    
    // Beginn des Einlesens - Header
    bool readHeader(FILE* pFile, TMapQDat& pMap)
    {
    	fread(&pMap.mHeader, 1, sizeof(THeader), pFile);
    
    	return isValid(pMap);
    }
    
    // 1. Einlesen Staedte 
    void readStadt(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbStaedte = pMap.mHeader.mContainers[cStadtContainer].mLength / sizeof(TStadt);
    
    	fseek(pFile, pMap.mHeader.mContainers[cStadtContainer].mOffset, SEEK_SET);
    
    	for
    		(int lStadtCounter = 0; lStadtCounter < lNbStaedte; ++lStadtCounter)
    	{
    		TStadt lStadt;
    
    		fread(&lStadt, 1, sizeof(TStadt), pFile);
    
    		pMap.mStaedte.push_back(lStadt);
    	}
    }
    
    // 2. Einlesen Coordinates
    void readCoordinate(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbData3 = pMap.mHeader.mContainers[cCoordinateContainer].mLength / sizeof(TCoordinate);
    
    	fseek(pFile, pMap.mHeader.mContainers[cCoordinateContainer].mOffset, SEEK_SET);
    
    	for
    		(int lCoordinateCounter = 0; lCoordinateCounter < lNbData3; ++lCoordinateCounter)
    	{
    		TCoordinate lCoordinate;
    
    		fread(&lCoordinate, 1, sizeof(TCoordinate), pFile);
    
    		pMap.mCoordinates.push_back(lCoordinate);
    	}
    }
    
    // 3. Einlesen Infos
    void readInfo(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbInfos = pMap.mHeader.mContainers[cInfoContainer].mLength / sizeof(TInfo);
    
    	fseek(pFile, pMap.mHeader.mContainers[cInfoContainer].mOffset, SEEK_SET);
    
    	for
    		(int lInfoeCounter = 0; lInfoeCounter < lNbInfos; ++lInfoeCounter)
    	{
    		TInfo lInfo;
    
    		fread(&lInfo, 1, sizeof(TInfo), pFile);
    
    		pMap.mInfos.push_back(lInfo);
    	}
    };
    
    // Vorbereiten der Datenausgabe
    void debugInformations(const TMapQDat& pMap, FILE* pFile)
    {
    	// Prüfen des Datenstreams
    	if
    		(! pFile)
    	{
    		printf("debugInformations :: Invalid stream handle.\n");
    		return ;
    	}
    
    	// Prüfen der Daten
    	if
    		(! isValid(pMap))
    	{
    		printf("debugInformations :: Invalid QDat-header.\n");
    		return;
    	}
    
    	// Start der Datenausgabe
    	fprintf(pFile, "Stand: 04.09.2010\n");
    
    	// Ausgabe 01 - Staedte
    	fprintf(pFile, "\n01 - Stadt Container\n");
    	fprintf(pFile, "#;Stadt\n");
    	for
    		(int lStadtCounter = 0; lStadtCounter < pMap.mStaedte.size(); ++lStadtCounter)
    	{
    	fprintf(pFile, "%d;%s\n", lStadtCounter, pMap.mStaedte[lStadtCounter].mName);
    	}
    	fprintf(pFile, "\n");
    
    	// Ausgabe 02 - Info-Side-Koordinaten
    	fprintf(pFile, "\n02 - Coordinate\n");
    	fprintf(pFile, "#;Koordinate*;Stadt(Index) - *nach 6 Koordinaten kommt eine Nummerierung\n");
    	for
    		(int lCoordinateCounter = 0; lCoordinateCounter < pMap.mCoordinates.size(); ++lCoordinateCounter)
    	{
    		fprintf(pFile, "%d;%f;%d\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mCoordinates[lCoordinateCounter].mStadtIndex);
    	}
    	fprintf(pFile, "\n");
    
    	// Ausgabe 03 - Info-Informationen
    	fprintf(pFile, "\n03 - Info Container\n");
    	fprintf(pFile, "#;Anzahl Koordinaten;Stadt(Index)\n");
    	for
    		(int lInfoCounter = 0; lInfoCounter < pMap.mInfos.size(); ++lInfoCounter)
    	{
    		fprintf(pFile, "%d;%d;%d\n", lInfoCounter, pMap.mInfos[lInfoCounter].mNbData3, pMap.mInfos[lInfoCounter].mStadtIndex);
    	}
    	fprintf(pFile, "\n");
    
    }
    // Lesen der Dateiinformationen
    bool readMap(const std::string& pFilename, TMapQDat& pMap)
    {
    	// Öffnen
    	FILE* lFile = fopen(pFilename.c_str(), "r+b");
    
    	// Prüfen ob vorhanden
    	if
    		(! lFile)
    	{
    		printf("readMap :: Invalid stream handle.\n");
    		return false;
    	}
    
    	// Lesen des Headers
    	if
    		(readHeader(lFile, pMap) == false)
    	{
    		printf("readMap :: Invalid QDat-header.\n");
    		return false;
    	}
    
      // Einlesen der Container:
      readStadt(lFile, pMap);
      readCoordinate(lFile, pMap);
      readInfo(lFile, pMap);
    
    	// Schließen der Datei
    	fclose(lFile);
    
    	return true;
    };
    
    void freeMap(TMapQDat& pMap)
    {
      pMap.mStaedte.clear();
      pMap.mCoordinates.clear();
      pMap.mInfos.clear();
    }
    
    //QDAT-Decrypter.cpp
    //Verweis auf Quell- und Zieldatei
    
    #include "QDATDecrypter.h"
    #pragma pack(push, MAIN)
    #include <cstdlib>
    #pragma pack(pop, MAIN)
    #include <iostream>
    using namespace std;
    
    int main(int pArgc, char** pArgv)
    {
    	TMapQDat	lMap;
    
    	cout<<"\nQDAT-Decrypter\nStand: 04.09.2010\n\n";
    	cout<<"Zu konvertierende Datei bitte in decrypt_me.QDAT umbenennen.\nENTER druecken wenn die Konvertierung begonnen werden kann.\n";cin.get();
    
    	readMap("decrypt_me.QDAT", lMap);
    
    	cout<<"Datei eingelesen. Konvertierung beginnt.\n";
    
    	FILE*	lFile = fopen("QDAT-Daten.txt", "w+");	
    	debugInformations(lMap, lFile);
    	fclose(lFile);
    
    	freeMap(lMap);
    
    	cout<<"\nKonvertierung erfolgreich beendet. \n\nDatei als Klartext mit dem Namen QDAT-Daten.txt gespeichert. \n\nZum Schliessen des Fensters bitte ENTER druecken!\n";cin.get();
    
    	return 0;
    };
    

    Entschuldigung für den schlechten Stil und den MischMasch zwischen C und C++. Noob am Werk. 😃
    Ich wäre für jeden Tipp dankbar, inmsbesondere wenn ich ihn als Anfänger und Hobbybastler auch verstehen und umsetzen kann. 🤡



  • noobLolo schrieb:

    hat hier nicht mal jemand geschrieben er verwendet vc++6.0 mit vista? evtl. läufts im kompatibilitäts modus? oder braucht admin rechte oder so?

    Ich verwende diese Kombination gelegentlich.
    Siehe auch: (ich hoffe mal, M.Richter hat nichts dagegen)
    http://blog.m-ri.de/index.php/2007/10/01/installation-von-vc6-unter-vista/



  • evilissimo schrieb:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
       unsigned Offset;
       unsigned Size;
    } ContainerInfo;
    
    int main()
    {
      #define GROESSE_CI 40
      ContainerInfo containerInfo[GROESSE_CI] = {0}; /* endlich mal einer, der auch richtig initialisiert */
      int i;
      FILE *inhaltsverzeichnis;
    
      inhaltsverzeichnis = fopen("test.dat", "rb");
      if( !inhaltsverzeichnis )
        perror("test.dat"),exit(EXIT_FAILURE);
      
      if( GROESSE_CI==fread(containerInfo, sizeof(ContainerInfo), GROESSE_CI, inhaltsverzeichnis) )
       for(i=0; i < GROESSE_CI; ++i) {
         printf("Datencontainer %d:    Anfang:   %x\n"    
                "                      Laenge:   %u Byte\n\n", 
                i+1, containerInfo[i].Offset, containerInfo[i].Size);
       }
      fclose( inhaltsverzeichnis );
      return EXIT_SUCCESS;
    }
    

    Ich hab mal ein paar Kleinigkeiten ergänzt.



  • Danke für die Info zum VS++6.0. Muss ich bei Gelegenheit nochmal testen.

    Zu meinem Problem 2 mit dem Verknüpfen der Daten. Ich hab gedacht ich könnte die Zeilen 130-132 einfach mit

    {
    int lstadtcode = fscanf(pFile, "%d", &pMap.mCoordinates[lCoordinateCounter].mStadtIndex);
    fprintf(pFile, "%d;%f;%s\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mStaedte[lstadtcode].mName);
    }
    

    oder

    {
    fprintf(pFile, "%d;%f;%s\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mStaedte[pMap.mCoordinates[lCoordinateCounter].mStadtIndex].mName);
    }
    

    ersetzen und bekomme dann die Stadt als Ausgabe aber beide Ideen crashen die Programmausführung. Fand ich eigentlich als tolle Idee denn wenn ich manuell z.B. pMap.mStaedte[1].mName für Stadt 1 einfüge bekomme ich diese in der Datenausgabe.

    Setze ich den int von lstadtcode auf 1 so klappt es auch und ich bekomme in diesem Fall Düsseldorf. Nur mit pMap.mCoordinates[lCoordinateCounter].mStadtIndex klappt es nicht. 😞

    { 
    int lstadtcode = 1; 
    fprintf(pFile, "%d;%f;%s\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mStaedte[lstadtcode].mName); 
    }
    


  • Also ich hab es hinbekommen das er den Stadtindex mit der Stadt ersetzt, dafür zerstört er aber die ausgegebene Datei in der Nummerierung (lCoordinateCounter)... 😕

    { 
    		fscanf(pFile, "%d", &pMap.mCoordinates[lCoordinateCounter].mStadtIndex); 
    		int lstadtcode;
    		lstadtcode = pMap.mCoordinates[lCoordinateCounter].mStadtIndex ;
    		fprintf(pFile, "%d;%f;%s\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mStaedte[lstadtcode].mName); 
    	}
    


  • Yeah, ich habs selber hinbekommen!!!!!! So geht's:

    { 
    		int lstadtcode;
    		lstadtcode = pMap.mCoordinates[lCoordinateCounter].mStadtIndex ;
    		fprintf(pFile, "%d;%f;%s\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mStaedte[lstadtcode].mName); 
    	}
    

    Nun bleiben nur noch Problem 1 und Problem 3. 😃



    Verwende statt

    readMap("decrypt_me.QDAT", lMap);
    
    readMap(pArgv[1], lMap);
    

    3. habe ich nicht verstanden.

    Ändert alles nichts daran, dass dies viel C++ Geraffel ist, dazu bekommst du in diesem Forum wohl kaum Lösungen angeboten.



  • Danke für Deine Hilfe! 🙂

    Wutz schrieb:

    Verwende statt

    readMap("decrypt_me.QDAT", lMap);
    
    readMap(pArgv[1], lMap);
    

    Das funktioniert wunderbar, nur wenn ich pArgv[1] auch für die zu schreibende Datei setze, dann überschreibt er mir natürlich das Original (sogar wenn es in einem anderen Ordner ist).

    FILE*	lFile = fopen(pArgv[1], "w+");
    

    Kann ich da dann noch eine andere Dateiendung oder Dateiart vorgeben? Wenn ich z.B. eine Datei mit dem Namen "Test01.dat" konvertiere würde ich gerne "Test01.txt" erzeugen oder zumindest "Test01.dat.txt". Ich hab's gerade mal probiert und bekomme Fehler wegen zuvielen Argumenten oder sowas.

    Wutz schrieb:

    3. habe ich nicht verstanden.

    Ich lese Koordinaten mit

    struct TCoordinate
    {
        float                mData3Index;            // Data3-Index  
        int                    mStadtIndex;            // Stadtindex  
    };
    

    ein. Die Koordinaten sind float, was ich auch gut einlesen kann. Leider sind zwischen den Floatzahlen manchmal auch einfache Zahlen (INT). Hier bekomme ich dann durch's falsche einlesen nur 0000.0000 statt der richtigen Dezimalzahl. Kann ich das prüfen und variabel mal als FLOAT und mal als INT einlesen?

    Wutz schrieb:

    Ändert alles nichts daran, dass dies viel C++ Geraffel ist, dazu bekommst du in diesem Forum wohl kaum Lösungen angeboten.

    Ups. Sollte ich mein Glück bei zukünftigen Fragen hierzu eher im C++ Forum suchen?



  • MS-Office-User schrieb:

    FILE*	lFile = fopen(pArgv[1], "w+");
    

    Das mach mal besser mit

    FILE*	lFile = fopen((strcpy(strstr(pArgv[1],".dat"),".txt"),pArgv[1]), "w+");
    


  • MS-Office-User schrieb:

    struct TCoordinate
    {
        float                mData3Index;            // Data3-Index  
        int                    mStadtIndex;            // Stadtindex  
    };
    

    ANSI C hat keine Vorgaben zum struct-alignment.
    Deine Versuche oben bei den includes sehen mir sehr suspekt aus.
    Für MSVC definiere einfach VOR der Definition deiner structs

    #pragma pack(1)
    

    und zu Beginn deines Codes teste dies z.B. mit

    assert( sizeof(TCoordinate) == (sizeof(float)+sizeof(int)) );
    

    und wenn du dann noch fread richtig verwendest, nämlich

    if( 1==fread( adressedeinerstrukturvariable, groessedeinerstruktur, 1, file ) )
      allesOK
    else
      Fehler
    

    sollte es funktionieren.



  • Wutz schrieb:

    Für MSVC definiere einfach VOR der Definition deiner structs

    #pragma pack(1)
    

    wenn du auf c und ms stehst dann geh ins winapi sufo sonst wär ein hinweis schon nicht schlecht das es nur dort klappt 😉



  • MS-Office-User schrieb:

    Wutz schrieb:

    Ändert alles nichts daran, dass dies viel C++ Geraffel ist, dazu bekommst du in diesem Forum wohl kaum Lösungen angeboten.

    Ups. Sollte ich mein Glück bei zukünftigen Fragen hierzu eher im C++ Forum suchen?

    #include <cstdio>
    

    läßt immer darauf schließen: "möchte gern und kann nicht recht".



  • Danke! Das hat mir sehr geholfen und ich hab in der Zwischenzeit auch schon viel geschafft bzw. gelöst. Sicherlich alles nicht perfekt und zu kompliziert bzw. zu "unprofessionell" aber es klappt. 😃

    Wo ich im Moment nicht weiterkomme ist beim Versuch die Anzahl eines bestimmten Zeichens von einem Text im Buffer einzulesen. Ich versuche es momentan so:

    int a = 0;
    for
    	(int i = 0; i < pMap.mTextteil.mSize; ++i)
    		{
    		char buchstabe = pMap.mTextteil.mBuffer[i];
    //      if (buchstabe == char(7B)); // Fehler	27	error C2059: Syntaxfehler: 'Ungültiges Suffix für Zahl'	
    		if (buchstabe == '{');
    			{
    			a = a + 1; 
    			}  
    		}
    fprintf(pFile, "\nAnzahl {: %d", a);
    

    Versuche ich es mit if (buchstabe == '{'); bekomme ich als Ausgabe die Anzahl aller Zeichen im Text (praktisch die Textlänge) und nicht nur die Anzahl aller Klammern. Versuche ich es mit char(7B) bekomme ich direkt beim Kompilieren einen Fehler. Es spielt auch keine Rolle ob ich nach der Klammer oder nach Buchstaben suche, ich bekomme immer die Länge des gesamten Textes als Ausgabe a, also praktisch pMap.mTextteil.mSize.

    Vielleicht seh ich den Wald vor lauter Bäumen nicht oder bin einfach nur zu doof, aber im Moment versteh ich es nicht. Den Ansatz find ich ok und denke es müsste an sich funktionieren... 😕



  • Uh, hab's selbst gesehen. Hinter die IF-Anweisung kommt natürlich kein ;
    🙄

    Jetzt geht's.



  • Ich möchte einzelne Datensätze aus dem Buffer löschen bevor ich ihn ausgebe.
    Ein Datensatz ist immer mit {}Klammern markiert. Ich möchte nun alle fehlerhaften bzw. die unnützen Datensätze rauswerfen indem ich nach Wörtern suche wie z.B. "unvollständig" oder "Duplikat". Bekommt man das mit fseek und verschachtelten if-Anweisungen hin? Die Datensätze können unterschiedlich lang sein, ich müsste also das Wort suchen, von da aus den Anfang ({) und das Ende (}) des gesamten Datensatzes bestimmen und dann den ganzen Satz aus dem Buffer löschen, denke ich.



  • Also ich hab es geschafft die Position der Datensätze die ein "" haben zu ermitteln. Was ich nicht schaffe sind ganze Wörter zu finden, nur diese "-Daten" auszugeben oder alle Daten ohne diese "*-Daten" auszugeben. Die gefundenen Positionen mit Fseek zu nutzen bring bisher nicht die richtigen Datensätze oder führt zu Fehlern bzw. Programmabstürzen. 😞

    int raus = 0;
    			for
    				(int is = 0; is < pMap.mTextteil.mSize; ++is)
    					{
    						char start = pMap.mTextteil.mBuffer[is];
    						if (start == '{')
    							{
    								int itemp = pMap.mTextteil.mSize;
    								for
    								(int ie = is; ie < itemp; ++ie)
    									{	
    										char ende = pMap.mTextteil.mBuffer[ie];
    										if (ende == '}')
    											{
    												for
    												(int im = is; im < ie; ++im)
    													{
    													char stern = pMap.mTextteil.mBuffer[im];
    													if (stern == '*')
    														{
    															raus = raus + 1;
    															fprintf(pFile, "Raus Nr. %d Start: %d Ende: %d * bei %d\n", raus, is, ie, im); 
    
    														}	
    
    													}															
    												itemp = ie;
    
    											}
    									}				
    							}
    					}
    


  • Wenn man so eine relativ umgrenzte Anforderung hat, schreibt man sich dafür eine Funktion, die sowas kapselt. Bekommst du nicht einen Fingerkrampf, wenn du ständig "pMap.mTextteil.mBuffer[ie]" o.ä. tippst?
    Mit "Buffer" meinst du wohl einen String?
    Dann könnte sowas wie folgt aussehen:

    int entferneDatensaetzeAus(char *s, const char **raus)
    { /* entfernt durch {} umschlossene Teilstrings aus s, für die ein <raus>-Kandidat vorliegt; <raus> := Stringliste NULL-terminiert; gibt Zahl der Entfernungen zurück; */
      int r=0;
      char *a=s,*e;
      while( (a=strchr(a,'{')) && (e=strchr(a,'}')) )
      {
        const char *f,**x=raus;    
        while( *x )
          if( (f=strstr(a+1,*x++)) && f<e )
          {
            ++r;
            memmove(a,e+1,strlen(e));
            e=a;
            break;
          }
        a=e;
      }
      return r;
    }
    

    Aufruf dann z.B.

    char *tabu[]={"unvollständig","Duplikat","*",0};
    int r=entferneDatensaetzeAus(pMap.mTextteil.mBuffer,tabu);
    


  • Naja, meine Lösung zur Positionsbestimmung war nicht schön aber ich war trotzdem stolz sie hinbekommen zu haben. 😃

    Whow, danke für Deinen Ansatz. Hab's schon mal auf die Schnelle ausprobiert und bekomme aber nur
    Fehler 1 error C2601: 'entferneDatensaetzeAus': Lokale Funktionsdefinitionen sind unzulässig
    für

    int entferneDatensaetzeAus(char *s, const char **raus) 
    {
    

    und
    Fehler 2 error C2664: 'entferneDatensaetzeAus': Konvertierung des Parameters 2 von 'char *[4]' in 'const char **' nicht möglich
    für

    int r=entferneDatensaetzeAus(pMap.mEntity.mBuffer,tabu);
    

    Muss ich mich nachher mal reindenken. Danke Dir! 🙂


Anmelden zum Antworten