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 StandardalgorithmenIch 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 weiterwas 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...