Zum Inhalt springen

fgets: warum wird "||-" mit eingelesen???


Woodstock

Empfohlene Beiträge

Also, ich schreibe ein Wort in eine Datei. Danach speicher ich diese. Wenn ich nun ein weiteres Wort habe, welches ich in die Datei schreiben möchte, aber zuerst schauen will ob es da nicht schon drin steht, lese ich Zeile für Zeile aus der Datei aus, und vergleiche das Ausgelesene und das Wort.

Nun zu meinem Problem: In der Datei steht immer nur ein Wort in jeder Zeile. Lasse ich mir nun das Ausgelesene ausgeben, stehen vor dem Wort noch ganz viel Zeichen die so ||- aussehen. Warum?

Hier mal mein Quelltext:

 void Ueberpruefen(char *szAusgelesenes, int& nPos, int& nA, int &nAnSuchw, char szEingabe[][1001], bool *afPruefung);

void Ausgabe(char *szSuchkriterium, int& nI, int& nA, bool *afPruefung, bool fFound, char *b, char szEingabe[][1001]);

void Schreiben(FILE *FT, FILE *FU, FILE *FV, FILE *FW, FILE *FX, FILE *FY, FILE *FZ, char *szAusgelesenes, long& nScnt, char *szBufferDateiPfad, char *;

void Auslesen(char *b, char szEingabe[][1001], int nAnSuchw, char* szSuchkriterium, long& nScnt)

{

	int nC, nPos = 0, nA = 0, nY = 0, nI, nD, result2, nScnt2=0, nB, nE;

	bool afPruefung[50], fFound;

	char szAusgelesenes[50], szBufferDateiPfad[501], szBufferIndex[501];

	char szBufferPfad[501], chA[20], chB[20], chC[20];

	char chD[20], chE[500], chF[500], szDoppelt[10000][50];

	FILE *FZ, *FW, *FX, *FV, *FY, *FT, *FU;



	strcpy(chA, "c:\\index.tmp.txt");

	strcpy(chB, "c:\\index.txt");

	strcpy(chC, "c:\\Pfad.tmp.txt");

	strcpy(chD, "c:\\Pfad.txt");

	strcpy(chE, "c:\\Datei.txt");

	strcpy(chF, "c:\\Datei.tmp.txt");


	FZ = fopen(b, "r");

	FX = fopen(chB, "r");

	FY = fopen(chC, "a+");

	FW = fopen(chA, "a+");

	FV = fopen(chD, "r");

	FU = fopen(chE, "r");

	FT = fopen(chF, "a+");


	for(nB=0;nB<10000;nB++)

		for(nE=0;nE<50;nE++)

			szDoppelt[nB][nE]=NULL;


	for(nI=0;nI<50;nI++)

		afPruefung[nI]=false;

	nC = 2;

	while (nC != EOF)

	{	

		nC = fgetc (FZ);

		if ((nC<'A'||nC>'z')||(nC>'Z'&&nC<'a')) 				

		{	

			szAusgelesenes[nPos] = '\0';

			_strlwr(szAusgelesenes);

			if(nScnt == 0)

			{	

				if(strlen(szAusgelesenes)>1)

				{

					fwrite(szAusgelesenes, sizeof(char), strlen(szAusgelesenes), FW);

					fwrite("\n", sizeof(char), strlen("\n"), FW);

					Schreiben1(FT, FU, FV, FW, FX, FY, FZ, szAusgelesenes, nScnt, szBufferDateiPfad, ;					

				} // if


			} // if			

			if(nScnt>0)

			{

				if(strlen(szAusgelesenes)>1)

				{

					fgets(szBufferIndex, 500, FX);

					cout << szBufferIndex << "\n";

					cin >> nD;


					while(fgets(szBufferIndex, 500, FX)!=0)

					{	

						_strlwr(szBufferIndex);

						for(nD=0; nD<nScnt2; nD++)

						{

							if(strcmp(szDoppelt[nD], szAusgelesenes)==0)

							{

								fFound = true;

								break;

							}

						}

						if(fFound == false)

						{

							fwrite(szAusgelesenes, sizeof(char), strlen(szAusgelesenes), FW);

							fwrite("\n", sizeof(char), strlen("\n"), FW);

							     strcpy(szDoppelt[nScnt2], szAusgelesenes);

							nScnt2++;

						}

					} // while


				} // if							

			} // if


			nA = 0;

			//Ueberpruefen(szAusgelesenes, nPos, nA, nAnSuchw, szEingabe, afPruefung);

			nPos = 0;

		} // if

		else

		{

			szAusgelesenes[nPos] = nC;

			nPos++;

		} // else

	} // while


//	Ausgabe(szSuchkriterium, nI, nA, afPruefung, fFound, b, szEingabe);

	fclose(FX);

	fclose(FZ);

	fclose(FW);

	fclose(FV);

	fclose(FY);

	fclose(FT);

	fclose(FU);

	remove(chE);

	remove(chB);

	remove(chD);

	rename(chF, chE);

	rename(chA, chB);

	rename(chC, chD);


} // Auslesen [/code]

Könnt Ihr mir da helfen?

Bine

Link zu diesem Kommentar
Auf anderen Seiten teilen

hast du dir diese datei mal mit notepad oder so angesehen? sieht die da auch so aus? ich nehme mal an, daß es sich um eine ganz normale textdatei handelt ...

wenn die datei im editor auch so aussieht, liegt der hase entweder beim rausschreiben begraben, oder beim einlesen. da du deinen quelltext nicht kommentiert hast ("wink mit dem zaunpfahl") kann ich dir so direkt nicht weiterhelfen ...

übrigens kannst du mit fgets direkt ganze zeilen einlesen. wenn du eh immer nur ein wort pro zeile drinstehen hast, kannst du dir damit diese zeichenabfragerei sparen ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also, es haldelt sich um eine ganz normale Textdatei, richtig. Im Editor sieht die nicht so aus, sondern ganz normal. Und zu dem Zeichenweise einlesen kann ich nur sagen, das später auch mehr in einer Zeile stehen soll, als ein Wort, und von daher ich das direkt mit fgets machen wollte, und nicht mit fgetc. Was soll ich zu dem kommentierren sagen? Also, las es mich nochmal versuchen:

 #include "Sabine(1).h"


void Ueberpruefen(char *szAusgelesenes, int& nPos, int& nA, int &nAnSuchw, char szEingabe[][1001], bool *afPruefung); // deklaration einer weiteren Funktion (ist im Moment noch auskommentiert, wird also nicht gebraucht)

void Ausgabe(char *szSuchkriterium, int& nI, int& nA, bool *afPruefung, bool fFound, char *b, char szEingabe[][1001]); // deklaration einer weiteren Funktion (ist im Moment noch auskommentiert, wird also nicht gebraucht)

void Schreiben(FILE *FT, FILE *FU, FILE *FV, FILE *FW, FILE *FX, FILE *FY, FILE *FZ, char *szAusgelesenes, long& nScnt, char *szBufferDateiPfad, char *; // Deklaration einer weiteren Funktion (folgt am Ende, für Euch)


void Auslesen(char *b /*übergibt den Pfad der Datei welche auf Suchbegriffe durchsucht wird */, char szEingabe[][1001] /* da steht der Suchbegriff drin */, int nAnSuchw /* Anzahl der Suchworte, zur Überprüfung später wichtig */,

			  char* szSuchkriterium /* Suchworte und/oder */, long& nScnt /* Zähler wie viele Worte insgesamt aus den Dateien ausgelesen wurden */)

{

	int nC, nPos = 0, nA = 0, nY = 0, nI, nD, result2, nScnt2=0, nB, nE;

	bool afPruefung[50], fFound;

	char szAusgelesenes[50], szBufferDateiPfad[501], szBufferIndex[501];

	char szBufferPfad[501], chA[20], chB[20], chC[20];

	char chD[20], chE[500], chF[500], szDoppelt[10000][50];

	FILE *FZ, *FW, *FX, *FV, *FY, *FT, *FU;


	// Strings mit dem Dateipfad wird in eine Variable kopiert, damit ich die Datei öffnen, schließen, umbenennen und später auch den Pfad ausgeben kann

	strcpy(chA, "c:\\index.tmp.txt"); 

	strcpy(chB, "c:\\index.txt");

	strcpy(chC, "c:\\Pfad.tmp.txt");

	strcpy(chD, "c:\\Pfad.txt");

	strcpy(chE, "c:\\Datei.txt");

	strcpy(chF, "c:\\Datei.tmp.txt");


	// öffnen der Dateien, um daraus zu lesen 'r' und darin zu schreiben (anhängen) 'a+'

	FZ = fopen(b, "r");

	FX = fopen(chB, "r");

	FY = fopen(chC, "a+");

	FW = fopen(chA, "a+");

	FV = fopen(chD, "r");

	FU = fopen(chE, "r");

	FT = fopen(chF, "a+");


	// Array zu Überprüfen ob ein Wort in der geöffneten Datei, aus der die Worte mit fgetc einzeln eingelesen und weiter verarbeitet werden, bereits schon einmal vorkommt, wird bei jeder neuen zu durchsuchenden Datei geleert

	for(nB=0;nB<10000;nB++)

		for(nE=0;nE<50;nE++)

			szDoppelt[nB][nE]=NULL;


	// boolsches Array wird kommplett auf false gesetzt (ist später für die Ausgabe wegen dem Suchkriterium von Bedeutung) 	

	for(nI=0;nI<50;nI++)

		afPruefung[nI]=false;


	nScnt2 = 0;	

	nC = 2; // damit nC nicht zufälligerweise beim ersten Durchgang EOF ist

	while (nC != EOF) // Zeichen werden aus Datei ausgelesen bis zum Dateiende

	{	

		nC = fgetc (FZ); // auslesen

		if ((nC<'A'||nC>'z')||(nC>'Z'&&nC<'a')) // bis ein Zeichen kein Buchstabe ist (ich weiß so bekommt er auch keine Umlaute wie 'ä', 'ö', etc.

		{	

			szAusgelesenes[nPos] = '\0'; // hat er ein Wort eingelesen hängt er zum erkennen ein Nullzeichen an

			_strlwr(szAusgelesenes); // string wird auf lowercase gesetzt

			if(nScnt == 0) // erstes Wort

			{	

				if(strlen(szAusgelesenes)>1)

				{

					fwrite(szAusgelesenes, sizeof(char), strlen(szAusgelesenes), FW); // Wort wird in eine Temporäre Datei geschrieben

					fwrite("\n", sizeof(char), strlen("\n"), FW); // Zeilenumbruch wird in dir Datei geschrieben

				} // if

			} // if			

			if(nScnt>0) // zweites bzw. weiteres Wort

			{

				if(strlen(szAusgelesenes)>1)

				{

					while(fgets(szBufferIndex, 500, FX)!=0) // aus der Temporären Datei, welche in eine nicht temporäre umgenannt wurde, wird solange immer eine Zeile ausgelesen um verarbeitet bis sie zu ende ist

					{	

						_strlwr(szBufferIndex); // Ausgelesenes wird zur Sicherheit auf lowercase gesetzt (obwohl eigentlich bereits alles auf lower sein sollte)

						for(nD=0; nD<nScnt2; nD++) // Array mit den Wörtern die schon in der Datei standen und in die temporäre Datei kopiert wurden, wird nach und anch durchgegangen

						{

							if(strcmp(szDoppelt[nD], szAusgelesenes)==0) // Überprüfung ob das Wort bereits vorkam

							{

								fFound = true;

								break;

							}

						}

						if(fFound == false) // kam das Wort werder in einer der früheren Dateien bereits einmal vor, noch in der im Moment geöffneten dann...

						{

							fwrite(szAusgelesenes, sizeof(char), strlen(szAusgelesenes), FW); // s.o.

							fwrite("\n", sizeof(char), strlen("\n"), FW); // s.o.

							strcpy(szDoppelt[nScnt2], szAusgelesenes); // string wird in das Array kopiert, damit man ihn beim nächsten Wort wieder vergleichen kann

							nScnt2++; // Zähler für die Anzahl der Worte pro Datei

						}

					} // while


				} // if							

			} // if


			nA = 0;

			//Ueberpruefen(szAusgelesenes, nPos, nA, nAnSuchw, szEingabe, afPruefung); // hier findet später die Überprüfung statt ob die Wörter aus den Ausgelesenen Dateien die gesuchten Wörter sind

			nPos = 0; // Positionszähler wirs auf Null gesetzt, damit beim nächsten Wort welches aus der Datei zeichenweise gelesen wird auch wieder ganz vorne angefangen wird

		} // if

		else

		{

			szAusgelesenes[nPos] = nC; // Zeichen werden an die Position nPos in das Array szAusgelesenes geschrieben

			nPos++; // damit nächster Buchstabe eine Position weiter in das Array geschrieben wird

		} // else

	} // while


	//	Ausgabe(szSuchkriterium, nI, nA, afPruefung, fFound, b, szEingabe); // Hier findet später die Augabe statt, ob es sich bei den Worten um die gesuchten handelt

	// schließen der Dateien

	fclose(FX);

	fclose(FZ);

	fclose(FW);

	fclose(FV);

	fclose(FY);

	fclose(FT);

	fclose(FU);

	// löschen der nicht temporären Dateien

	remove(chE);

	remove(chB);

	remove(chD);

	// umgenennen der temporären Dateien in die geleichnamigen nicht-temporären Dateien

	rename(chF, chE);

	rename(chA, chB);

	rename(chC, chD);


} // Auslesen [/code]

Es soll später so laufen das ich eine Datei (z.B. index.txt) habe, in die ich alle Wörter schreibe, die ich den den Textdatei (z.B. balbalbal.txt, blubb.txt) die ich auf meinem Rechner (oder eben auch anderen) finde. Aber immer nur einmal. Also kein Wort doppelt. Deswegen öffne ich eine temporäre Datei (z.B. index.tmp.txt), in die ich alles schreibe was in der index.txt bereits drinsteht, und alles was neu kommt. Nachdem ich die komplette balbalbal.txt ausgelesen habe (und wenn dort Worte drin standen die ich noch nicht ausgelesen hatte, auch in die index.tmp.txt geschrieben habe), lösche ich die index.txt, und benenne die index.tmp.txt in index.txt um. Und verfahre dann genau so weiter mit jeder anderen Datei (z.B. der blubb.txt).

Viel später sollen dann nur noch die Dateien so duchsucht werden die seit dem letzten durchsuchen neu dazu gekommen sind (aber das ist ja im Moment nicht wichtig). Und im Grunde werden damit dann nicht mehr alle auf der Festplatte befindlichen Datein auf die gesuchten Worte hin untersucht, sondern nur noch diese eine Datei. Die Ausgabe wird dann mit dem Pfad verbunden (will das so machen das ich immer wenn ich ein Wort in die temporäre Datei schreibe dann auch den Pfad in eine andere temporäre Datei zu schreiben, bzw. wenn er das Wort schon einmal in die temporäre Datei geschrieben habe, an der Stelle dann den Pfad welcher schon existiert mit dem neuen Pfad ergänze. So will ich dann später die Wörter mit den Pfaden ausgeben können.

Bine

PS: Ich hoffe jetzt bist Du nicht total verwirrt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

zitat: "if ((nC<'A'||nC>'z')||(nC>'Z'&&nC<'a')) "

muß da nicht ein && hin?

"if ((nC<'A' && nC>'z')||(nC>'Z'&&nC<'a'))"

den rest schau ich mir morgen an, ich muß los ...

zum thema einlesen:

du kannst ruhig auch die ganze zeile einlesen, und dann den string durchparsen. du wirst dann ja ein trennzeichen zwischen den einzelnen parametern haben und kannst dann in dem string in dem die komplette zeile steht immer alles bis zu diesem trennzeichen einlesen.

das ist (meist) schneller, in jedem fall aber übersichtlicher.

ich hab mir für solche zwecke eigens eine funktion geschrieben, der die komplette zeile übergeben wird und diese an einem trennzeichen splittet. das gesplittete wird in einem vektoren abgelegt. ein vektor ist so was wie ein array nur auf c++.

so etwas in der art könntest du dir ja auch mit nem array basteln, da du ja genau weißt, wie viele parameter pro zeile vorkommen werden. durch den index des arrays kannst du dann nach dem splitten problemlos auf die einzelnen elemente zugreifen.

ciao, ich muß wech :D

-Poldi-

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nee, da muss kein && das klappt ja so wie es soll (stammt ja schon aus einem etwas älteren Programm, wo ich einfach die Dateien durchsuche, und nichts daraus schreibe, und das klappt alles sehr gut). Nur weil es eben sehr lange dauert bis ich die ganze Festplatte durchsucht habe (was dann ja nur noch sporadisch passieren soll), soll ich das Programm so umschreiben!

Bine

Link zu diesem Kommentar
Auf anderen Seiten teilen

 while ( fgets(szBufferIndex, 500, FX) !=0 ) // aus der Temporären Datei, welche in eine nicht temporäre umgenannt wurde, wird solange immer eine Zeile ausgelesen um verarbeitet bis sie zu ende ist

{ 

_strlwr(szBufferIndex); // Ausgelesenes wird zur Sicherheit auf lowercase gesetzt (obwohl eigentlich bereits alles auf lower sein sollte)

for(nD=0; nD<nScnt2; nD++) // Array mit den Wörtern die schon in der Datei standen und in die temporäre Datei kopiert wurden, wird nach und anch durchgegangen

{

if(strcmp(szDoppelt[nD], szAusgelesenes)==0) // Überprüfung ob das Wort bereits vorkam

{

fFound = true;

break;

}

}

 

du speicherst das wort aus der datei in die Variable szBufferIndex, vergleichst hinterher aber szDoppelt mit szAusgelesenes. was willst du an dieser stelle womit vergleichen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, das ist mir heute morgen auch aufgefallen :) . Habe das schon geändert :D :

 	while(fgets(szBufferIndex, 500, FX)!=0)

	{	

		cout << "Hallo\n";

		_strlwr(szBufferIndex);

		for(nD=0; nD<nScnt2; nD++)

		{

			if(strstr(szDoppelt[nD], szAusgelesenes)==0)

			{						

			        cout << "Schade\n";

				fFound = true;

				//	SchreibenJa(a, FT, FU, FV, FW, FX, FY, FZ, szAusgelesenes, szBufferPfad, szBufferDateiPfad, ;					break;

			}

		}

		if(strstr(szBufferIndex, szAusgelesenes)==0)

		{

			cout << "Schade\n";

			fFound = true;

		}


	} // while

	if(fFound == false)

	{

		Schreiben(FT, FU, FV, FW, FX, FY, FZ, szAusgelesenes, nScnt, szBufferDateiPfad, ;

		strcpy(szDoppelt[nScnt2], szAusgelesenes);

		nScnt2++;

	} [/code]

Außerdem kopiere ich am Anfang jetzt ersteinmal den kompletten Inhalt von index.txt in index.tmp.txt, damit ich bei weiteren Durchläufen die bereits herausgeschriebenen Wörter nicht verliere, was ja passiert, wenn ich nur die neuen Sachen mit den alten vergleiche, und nur die neuen Sache (die noch nicht vorkamen) in die index.tmp.txt schreibe. Dann ist das was in index.txt drin stand nach dem umbennen ja weg.

Aber so ganz wie es soll läuft es immer noch nicht. Er fügt ganz viele leere Zeilen in meine index.txt ein :confused: .

Bine

<FONT COLOR="#a62a2a" SIZE="1">[ 13. Dezember 2001 11:37: Beitrag 2 mal editiert, zuletzt von Woodstock ]</font>

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...