Suchen&Ersetzen....Wer findet meinen Fehler?



  • Hallo,
    ich hab versucht in C/C++ ein Programm zu schreiben das in einem Text nach Abkürzungen sucht und sie durch ihre Langformen ersetzt.
    Beides steht in einer Liste.

    Mein Program läuft zwar aber es tut nicht das was es soll und ich finde meinen Fehler grad einfach nicht.
    Wär nett wenn mir vielleicht jemand helfen könnte.

    // Header einbinden
    #include<iostream>
    #include<fstream>
    #include <cstdlib>
    #include<stdlib.h>
    using namespace std;
    
    // Deklarieren der Globalen Variablen
    char cTextfilePfad[30];
    char cAbkListenPfad[30];
    char cAusgabefile[30];
    char cScanBlock[400];		// 255 verwendete Zeichen + 145 Zeichen Buffer für Ersetzungen 
    char cAbkZeile[255];
    int iFC=0;					// Fehlercode: 0 -> OK; 1 -> Fehler
    int iAnzahlErsetzungen = 0;
    char Taste;					// fuer Menüs, usw...
    int iCurrPos_Abk = 0;
    int iCurrCh_Abk = 0;
    int iCurrPos_Block = 0;
    int iCurrCh_Block = 0;
    int d=0;					// wichtig für ScanBlock einlesen
    int ErsetzungsPos[255];	
    int AbkLaenge = 0;
    int LangformAnfangPos = 0;
    int Langformlaenge = 0;
    int Platz = 0;				// um wieviele Zeichen ist Abk länger als ihre Ersetzung?				
    
    // Funktionendeklaration
    int CleanAndClear(void);	// Filezugriffe und Suche
    int Ersetzen(void);			// ersetzt gefundene Abk; wird von Suchen() aufgerufen
    int WriteToNewText(void);	// schreibt die veränderten Daten in das neue Textfile
    
    int main(void)
    {
    	cout << "\nAbkuerzungsersetzungstool\n---------------------------------\n";
    
    /*	cout << "\nQuelltextfile >>";
    	cin >> cTextfilePfad;
    	cout << "\nAbkListe >>";
    	cin >> cAbkListenPfad;
    	cout << "\nAusgabefile >>";
    	cin >> cAusgabefile;
    */	
    	cout << "Das Programm durchsucht nun die Textdatei nach in der Liste stehenden\n";
    	cout << "Abkuerzungen.\nDiese wird es dann durch die ebefalls in der Liste stehende";
    	cout << "Langform ersetzen.\n\nDie Liste muss folgende formatierung haben:";
    	cout << "\n\t<Abkuerzung><Leerzeichen>:<Leerzeichen><Langform>\n\nBeispiel:";
    	cout << "\n\tusw. : und so weiter\n\n";
    	CleanAndClear();
    
    	cout << "\a\n-----------------------------------------\n";
    	cout << "Suchen und Ersetzen beendet....\n";
    	cout << "Es wurden " << iAnzahlErsetzungen << " Ersetzungen vorgenommen\n";
    	cout << "Zum Beenden <Return> druecken\n";
    	while (cin.get(Taste) && Taste != '\n');
    	return 0;
    }
    
    int CleanAndClear(void)
    {
    	bool fertig = false;
    
    	// Stream einrichten
    	ifstream Text;
    	ifstream Liste;
    	ofstream Ausgabe;
    	// Files öffnen
    	Text.open("Quelltext.txt", ios_base::in | ios_base::beg);
    	Liste.open("AbkListe.txt", ios_base::in | ios_base::beg);
    	Ausgabe.open("Ausgabefile.txt", ios_base::app);
    
    	while(fertig==false)
    	{
    		// Positionen der zu ersetzenden Wörter reseten
    		for(int k=0;k<=255;k++)
    		{
    			ErsetzungsPos[k] = 0;
    		}
    
    		// 255 Zeichen des Textes raussuchen
    		for(int i=0; i<255; i++)
    		{
    			char Temp;
    			Text.seekg(i+d);
    			Text.get(Temp);
    			cScanBlock[i] = Temp;
    			iCurrCh_Block++;
    		}
    		cScanBlock[255] = '\0';
    		d += 255;
    
    		while(Liste.ios::eof==false)
    		// Eine Zeile der Liste einlesen
    		Liste >> cAbkZeile;
    
    		// Die erste Zeile heraussuchen, Positionen speichern und den Rest löschen
    		for(i=0;i<=255;i++)
    		{
    			Liste.seekg(iCurrPos_Block);
    			if(cAbkZeile[i]=='\n')
    			{
    				iCurrPos_Abk = Liste.tellg();
    				iCurrCh_Abk = i;
    				break;
    			}
    		}
    		for(int j=i; j<=255; j++)
    		{
    			cAbkZeile[j] = '\0';
    		}
    
    		// Wie lang ist die Abk?
    		for(int p=0;p<=25;p++)
    		{
    			if(cAbkZeile[p]==':')
    			{
    				AbkLaenge = p-1;
    			}
    		}
    		LangformAnfangPos = p+2;
    
    		// Wie lang ist die Langform?
    		for(p=0;p<=255;p++)
    		{
    			if(cAbkZeile[p]=='\0')
    				Langformlaenge = (p-1) - LangformAnfangPos;
    		}
    
    		// jetzt wird gescannt
    		for (i=0; i<=255;i++)
    		{
    			if(cScanBlock[i]=='\0')
    				break;
    			for(int m=AbkLaenge; m>0; m--)
    			{
    				if(cScanBlock[i]!=cAbkZeile[m])
    					break;
    				if(m==1)
    					ErsetzungsPos[i] = 1;
    			}
    		}
    
    		// Jetzt werden die gefundenen Abk. ersetzt
    		Ersetzen();
    
    		// in die Ausgabe schreiben
    		Ausgabe << cScanBlock;
    
    		// fertig?
    		if((bool)Text.ios::eof==true)
    			fertig = true;
    
    		// und weiter....
    		return 0;
    	}
    }
    
    int Ersetzen(void)
    {
    	int d=0;
    	// Daten retten
    	for(int n=0;n<=255;n++)
    	{
    		if(ErsetzungsPos[n]==1)
    		{
    			for(int i=255;i>=0;i--)
    				cScanBlock[i] = cScanBlock[i+Langformlaenge];
    		}
    	}
    
    	// Langformen einfügen
    	for(n=0;n<=255;n++)
    	{
    		if(ErsetzungsPos[n]==1)
    		{
    			iAnzahlErsetzungen++;
    			for(int j=LangformAnfangPos;j<=(LangformAnfangPos+Langformlaenge);j++)
    			{
    				cScanBlock[n+d] = cAbkZeile[j];
    				d++;
    			}
    		}
    	}
    	return 0;
    }
    

    Bis dann
    Cray



  • so ich hab's mal etwas standardkonformer gemacht, damit der gcc es auch schlucken kann:

    // Header einbinden 
    #include<iostream> 
    #include<fstream> 
    #include <cstdlib> 
    //sdlib.h == cstdlib im namensraum std
    using namespace std; 
    
    // Deklarieren der Globalen Variablen 
    char cTextfilePfad[30]; 
    char cAbkListenPfad[30]; 
    char cAusgabefile[30]; 
    char cScanBlock[400];        // 255 verwendete Zeichen + 145 Zeichen Buffer für Ersetzungen  
    char cAbkZeile[255]; 
    int iFC=0;                    // Fehlercode: 0 -> OK; 1 -> Fehler 
    int iAnzahlErsetzungen = 0; 
    char Taste;                    // fuer Menüs, usw... 
    int iCurrPos_Abk = 0; 
    int iCurrCh_Abk = 0; 
    int iCurrPos_Block = 0; 
    int iCurrCh_Block = 0; 
    int d=0;                    // wichtig für ScanBlock einlesen 
    int ErsetzungsPos[255];     
    int AbkLaenge = 0; 
    int LangformAnfangPos = 0; 
    int Langformlaenge = 0; 
    int Platz = 0;                // um wieviele Zeichen ist Abk länger als ihre Ersetzung?                 
    
    // Funktionendeklaration 
    int CleanAndClear(void);    // Filezugriffe und Suche 
    int Ersetzen(void);            // ersetzt gefundene Abk; wird von Suchen() aufgerufen 
    int WriteToNewText(void);    // schreibt die veränderten Daten in das neue Textfile 
    
    int main(void) 
    { 
        cout << "\nAbkuerzungsersetzungstool\n---------------------------------\n"; 
    
    /*    cout << "\nQuelltextfile >>"; 
        cin >> cTextfilePfad; 
        cout << "\nAbkListe >>"; 
        cin >> cAbkListenPfad; 
        cout << "\nAusgabefile >>"; 
        cin >> cAusgabefile; 
    */     
        cout << "Das Programm durchsucht nun die Textdatei nach in der Liste stehenden\n"; 
        cout << "Abkuerzungen.\nDiese wird es dann durch die ebefalls in der Liste stehende"; 
        cout << "Langform ersetzen.\n\nDie Liste muss folgende formatierung haben:"; 
        cout << "\n\t<Abkuerzung><Leerzeichen>:<Leerzeichen><Langform>\n\nBeispiel:"; 
        cout << "\n\tusw. : und so weiter\n\n"; 
        CleanAndClear(); 
    
        cout << "\a\n-----------------------------------------\n"; 
        cout << "Suchen und Ersetzen beendet....\n"; 
        cout << "Es wurden " << iAnzahlErsetzungen << " Ersetzungen vorgenommen\n"; 
        cout << "Zum Beenden <Return> druecken\n"; 
        while (cin.get(Taste) && Taste != '\n'); 
        return 0; 
    } 
    
    int CleanAndClear(void) 
    { 
        bool fertig = false; 
        // Files öffnen 
        ifstream Text ("Quelltext.txt"); 
        ifstream Liste ("AbkListe.txt"); 
        ofstream Ausgabe ("Ausgabefile.txt", ios::app); //ans ende anhängen- sicher?
    
        while(fertig==false) 
        { 
            // Positionen der zu ersetzenden Wörter reseten 
            for(int k=0;k<=255;k++) 
            { 
                ErsetzungsPos[k] = 0; 
            } 
    
            // 255 Zeichen des Textes raussuchen 
            for(int i=0; i<255; i++) 
            { 
                char Temp; 
                Text.seekg(i+d); 
                Text.get(Temp); 
                cScanBlock[i] = Temp; 
                iCurrCh_Block++; 
            } 
            cScanBlock[255] = '\0'; 
            d += 255; 
    
            while(Liste.eof()==false) //das ist eine funktion, der datenmember ist private
            // Eine Zeile der Liste einlesen 
            Liste >> cAbkZeile; 
    
            // Die erste Zeile heraussuchen, Positionen speichern und den Rest löschen 
    		  int i = 0;
            for(;i<=255;i++)
            { 
                Liste.seekg(iCurrPos_Block); 
                if(cAbkZeile[i]=='\n') 
                { 
                    iCurrPos_Abk = Liste.tellg(); 
                    iCurrCh_Abk = i; 
                    break; 
                } 
            } 
            for(int j=i; j<=255; j++) 
            { 
                cAbkZeile[j] = '\0'; 
            } 
    
            // Wie lang ist die Abk? 
    		  int p=0;
            for(;p<=25;p++) 
            { 
                if(cAbkZeile[p]==':') 
                { 
                    AbkLaenge = p-1; 
                } 
            } 
            LangformAnfangPos = p+2; 
    
            // Wie lang ist die Langform? 
            for(p=0;p<=255;p++) 
            { 
                if(cAbkZeile[p]=='\0') 
                    Langformlaenge = (p-1) - LangformAnfangPos; 
            } 
    
            // jetzt wird gescannt 
            for (i=0; i<=255;i++) 
            { 
                if(cScanBlock[i]=='\0') 
                    break; 
                for(int m=AbkLaenge; m>0; m--) 
                { 
                    if(cScanBlock[i]!=cAbkZeile[m]) 
                        break; 
                    if(m==1) 
                        ErsetzungsPos[i] = 1; 
                } 
            } 
    
            // Jetzt werden die gefundenen Abk. ersetzt 
            Ersetzen(); 
    
            // in die Ausgabe schreiben 
            Ausgabe << cScanBlock; 
    
            // fertig? 
            if(Text.eof()) 
                fertig = true; 
    
            // und weiter.... 
            return 0; 
        } 
    } 
    
    int Ersetzen(void) 
    { 
        int d=0; 
        // Daten retten 
        for(int n=0;n<=255;n++) 
        { 
            if(ErsetzungsPos[n]==1) 
            { 
                for(int i=255;i>=0;i--) 
                    cScanBlock[i] = cScanBlock[i+Langformlaenge]; 
            } 
        } 
    
        // Langformen einfügen 
        for(int n=0;n<=255;n++)
        { 
            if(ErsetzungsPos[n]==1) 
            { 
                iAnzahlErsetzungen++; 
                for(int j=LangformAnfangPos;j<=(LangformAnfangPos+Langformlaenge);j++) 
                { 
                    cScanBlock[n+d] = cAbkZeile[j]; 
                    d++; 
                } 
            } 
        } 
        return 0; 
    }
    

    Was mir auffällt:
    Du verwendes viel zu viele globale Variablen.
    Du deklarierst alle Variablen am Anfang einer neuen Funktion und verwendest sie irgendwann später.
    Du machst sehr lange Funktionen
    Du verwendest kompliziertere for Schleifen (die denn Sinn verbergen), statt Standardalgorithmen

    Ich sag dir erstmal, was ich ausgebessert hab:

    #include <stdlib.h>
    

    stdlib.h ist dasselbe, wie cstdlib, nur ist cstdlib im Namensraum std

    for (int i = 0; i < bla; ++i) { /* ... */ }
    
    for (i = 0; /* ... */
    

    Laut Standard ist i nur in der ersten for Schleife gültig, du müsstest in der zweiten i neu deklarieren oder die deklaration von i vor der ersten for Schleife machen

    ofstream Ausgabe;
    Ausgabe.open("blubb");
    

    Hier verschwendest du Perfomence und Zeit (beim Tippen). Der Konstruktor von ofstream kann das, was du willst schneller:

    ofstream Ausgabe("blubb");
    

    Jetzt sag uns noch, was nicht funktioniert, und zeige, wie die Dateien (zumindest die Liste) aufgebaut sein muss.



  • also danke erstmal für den Ansatz

    die Liste ist folgendermaßen aufgebaut

    <Abkürzung><Leerzeichen>:<Leerzeichen><Langform>

    Bsp:
    usw. : und so weiter

    was ist so schlimm an den vielen Globalen Variablen?

    Das Problem bei dem Programm ist das es aus irgendeinem Grund nicht das tut was es tun soll.....
    ich weiß irgendwo hab ich einem Logikfehler aber ich komm einfach nicht dahiner



  • der code ist zu unübersichtlich, deshalb will ihn sich auch keiner ansehen.
    versuche, den fehler einzugrenzen.
    lass dir z.b. die eingelesenen wörter ausgeben, etc.



  • hm,ja entschuldigen meinen schlechten Programmierstil aber wir habens in der Schule so beigebracht bekommen.

    Wie würdest du es denn lösen?
    Also mit welchem Konzept, mit welchen Algorithmen und Funktionen?

    Cray



  • also, ich habe das Programm nochmal geschrieben, hoffe es ist etwas lesbarer.
    Allerdings tritt eine Schutzverletzung auf



  • vielleicht liegt es an meinem browser, aber ich seh da keinen source-code, nur drei punkte...


Anmelden zum Antworten