Textdatei auslesen und eine andere Textdatei schreiben?



  • Hi !

    azoul schrieb:

    hat jemand eine ideee wie man das programmieren kann. ?

    Ja, ich hätte da die eine oder andere.
    Wofür brauchst du das, soll das mal in der Praxis laufen, oder ist das eine Schulaufgabe ?

    Für den ersten Fall ( bei großen Datenmengen ) würde ich eine andere Form des Speicherns wählen, bzw. eine
    ergänzende Form zur Bestehenden.
    Konkret: die Datei verkehrsdaten.txt in mehrere Dateien aufteilen.

    Die Dateinamen können dabei z.B. aus den Usernamen gebildet werden:
    user0_user1.txt. Doppelte Einträge sollen darin erst gar nicht gespeichert werden.
    Oder bilde doch die Dateinamen gleich aus der ganzen Zeile:
    A_192.168.0.84_5996_192.168.0.221_5890_0_user0_user1.txt
    Dann können erst gar keine doppelten Einträge entstehen, wenn die Existenz
    der Datei geprüft wird.
    Macht die Suche dach doppelten Einträgen schneller, ne.

    Wenns ne Schulaufgabe ist oder so, dann käme hier der Einsatz einer einfach Verketteten Liste in Frage oder char-Array-Blöcke. Die Zeilen können ja nicht nur doppelt, sonder auch drei-, vierfach usw. vorkommen.

    Mit Hashfunktionen und binärer Suche wirst du hier etwas mehr Aufwand haben, weil die Datei oder ihre Kopie dafür anders formatiert sein muss. Wäre aber auch ne gute Übung.
    Für die Hashsuche muss die maximale Anzahl der Zeilen im Voraus bekannt sein. Wird diese überschritten, so muss eine neue Datei erstellt und der ganze Kram umkopiert werden. Das ist irgendwie Käse, ne.
    Für eine binäre Suche, oder auch Halbierungssuche genannt, müsstest du die Zeilen vorher sortieren.

    Hashschlüssel bilden und danach dann binär suchen wäre allerdings, ohne jemandem zu nahe treten zu wollen, Käse hoch 7 😃 bzw. Doppelmoppelmurks.

    Das kannst du viel einfacher haben. Siehe obiger Vorschlag.

    Das mit deinen 'E-Zeilen' kapiere ich nicht so ganz, aber wenn du nur

    Gruß,
    B.B.



  • Big Brother Schrieb!

    die Datei verkehrsdaten.txt in mehrere Dateien aufteilen.

    Das Programm soll im Praxis laufen. und ist ein teil meiner Diplomarbeit
    Die Textdatei ist nicht fest, sie wird ständig von anderem Programm angehängt. wie kann ich die überhaupt in mehrere Dateien teilen??
    und das Programm soll für verschiedene IPs, PortNr und Namen funktionieren...??
    das ist das Problem bei der ganze Geschichte...

    Hat jemand noch andere idee wie das zu machen ist muss die Diplomarbeit in zwei wochen abgeben...



  • azoul schrieb:

    ... sie wird ständig von anderem Programm angehängt...

    Sind die Programme von dir ?
    Oder hast du gar keinen Einfluss darauf, wie die Daten gespeichert werden ?
    Wenn die Daten immer bloß angehängt werden dann wird die Datei irgendwann zu groß, ne.

    Vorhin ist mir bei copy/paste ein Teil verloren gegangen:
    Das mit deinen 'E-Zeilen' kapiere ich nicht so ganz, suchst du nach Zeilen die sich vorn nur durch ein E unterscheiden ?

    Wennste jetzt gar keinen Einfluss auf das Format hast dann lies doch erstmal die Datei in eine verkettete Liste ein und zwar so, das die Dublikate und deine zugeörigen E-Zeilen (was ich nicht so ganz kapiere) entfernt werden. Dann sicherst du die Dateizeigerposition, damit du den ganzen Salat nächstes mal wenn Daten dazukommen, nicht von vorn einlesen musst und speicherst deine Liste mit den Unikaten in eine andere Datei.



  • Big Brother Schrieb!

    Sind die Programme von dir ?
    Oder hast du gar keinen Einfluss darauf, wie die Daten gespeichert werden ?

    Hier das Problem vom Anfang: Habe OpenSER-Server(arbeitet als Proxy-Server), der die Daten in einer MySQL-Datenbank ablegt. Die Daten(IP-Adresse, Port-Nummer, codec und Name) sind von verschiedenen Teilnehmer, die den OpenSER-Server benutzt bzw. über ihn telefonieren. Die Daten, die in Datenbank abgelegt sind, werden von zwei verschiedene Programme ausgelesen(Die Programme werden von OpenSER_software aufgerufen sobald eine telefonat stattfindet) Ein Programm (select.c)liest die Daten(A 192.168.0.84 6066 102.168.0.221 7862 0 user user1) eine aufgebaute bzw. angefangene Telefonat, das andere programm(delete.c) liest die Daten (E 192.168.0.84 6066 102.168.0.221 7862 user user1) eine beendete Telefonat. die beide programme select.c und delete.c legen die daten in FIFO-Datei ab. danach werden von einem Programm ausgelesen und in der Textdatei Verkehrsdaten.txt angehängt. hoffe habe das problem deutlich beschrieben....

    die doppelte Einträge oder mehrfach vorkommene Einträge konnte ich vorher nicht verhindern in der Textdatei zu schreiben...



  • Hast du Email ? Dann schick ich dir mal was.
    Wenn du willst, kopiere ich das auch hier rein.
    Gruß,
    B.B.



  • Da war noch was...

    C schrieb:

    ...Die strtok Aufrufe kannst du mit einer Zeile sprintf ersetzen, macht das ganze kürzer und leserlich....

    Du meinst bestimmt sscanf.
    Guckst du hier:

    char* xxx = "E 192.168.0.84 5996 192.168.0.221 5890 0 user0 user1";
    void check_this_out()
    {
    	char AoE[8], ip1[64], ip2[64], port1[32], port2[32],
    	 codec[64], name1[64], name2[64];
    	sscanf ( xxx, "%s %s %s %s %s %s %s %s", AoE, ip1, ip2, port1, port2, codec, name1, name2 );
    	puts ( ip1 ); // usw..
    }
    


  • Big Brother Schrieb!

    Hast du Email ? Dann schick ich dir mal was.
    Wenn du willst, kopiere ich das auch hier rein.

    du kannst das auch hier rein kopieren..Danke



  • Ok, hier hast du nen Filter, der dir die Paare rausholt. Kannst du dir ja umschreiben oder so.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAXLINELEN 256 
    #define ANFANG 'A'
    #define ENDE 'E'
    
    void error_exit ( char* e )
    {
    	fcloseall ();
    	fprintf ( stderr, "%s\n", e );
    	exit (1);
    }
    
    int haveA ( char* A, char* file ) // Gibt es die A Zeile in der Datei 'file' ?
    {
    	FILE* fp = fopen ( file, "rt" );
    	char buf [MAXLINELEN];
    
    	if ( fp == NULL )
    		return 0; // Datei existiert( noch ) nicht, also auch nicht die Zeile.
    
    	while ( NULL != ( fgets ( buf, sizeof ( buf ), fp )))
    	{
    		if ( 0 != ferror ( fp ))
    			error_exit ( "fgets failed. " );
    
    		if ( 0 == strcmp ( A, buf ))
    		{
    			 if ( fclose ( fp ) )
    				error_exit ( "fclose failed. " );
    
    			return 1; // Zeile gefunden.
    		}
    	}
    
    	if ( fclose ( fp ) )
    		error_exit ( "fclose failed. " ); 
    
    	return 0; // Zeile nicht gefunden.
    }
    
    void addAB ( char* A, char* B, char* file ) // AE Paar zur Datei hinzufügen.
    {
    	FILE *fp = fopen ( file, "a+t" );
    
    	if ( NULL == fp ) 
    		error_exit ( "fopen failed. " );
    
    	fputs ( A, fp );
    	if ( ferror ( fp ) )
    		error_exit ( "fputs failed. " );
    
    	fputs ( B, fp );
    	if ( ferror ( fp ) )
    		error_exit ( "fputs failed. " );
    
    	if ( fclose ( fp ) )
    		error_exit ( "fclose failed. " );
    
    	return;
    }
    
    void uniquePairs ( char *Data, char* Result )
    {
    	char A [MAXLINELEN], B [MAXLINELEN];
    	FILE* fData;
    	fpos_t pos;
    
    	if ( NULL == ( fData = fopen ( Data, "rt" )))
    		error_exit ( "fopen failed. " );
    
    	while ( NULL != ( fgets ( A, sizeof ( A ), fData )))
    	{
    		if ( 0 != ferror ( fData ) )
    			error_exit ( "fgets failed. " );
    
    		if ( A [0] == ANFANG && 0 == haveA ( A, Result ))
    		{ // Zeile beginnt mit A und existiert nicht in feld.txt
    			if ( 0 != fgetpos ( fData, &pos )) // Dateizeiger sichern.
    				error_exit ( "fgetpos failed. " );
    
    			strcpy ( B, A );
    			B [0] = ENDE;
    
    			while ( NULL != ( fgets ( A, sizeof ( A ), fData )))
    			{ // Suche nach der zugehörigen E-Zeile
    
    				if ( 0 != ferror ( fData ) )
    					error_exit ( "fgets failed. " );
    
    				if ( 0 == strcmp ( A, B )) 
    				{ // Die zur A-Zeile zugehörige E-Zeile gefunden.
    					A [0] = ANFANG;
    					addAB ( A, B, Result ); // Unikat-Paar hinzufügen.
    
    					break; // Bricht die innere while-Schleife ab.
    				}
    			}
    
    			if ( 0 != fsetpos ( fData, &pos )) // Dateizeiger an gesicherte Position setzen.
    				error_exit ( "fgetpos failed. " );
    		}
    	}
    }
    
    int main()
    {
    	char *Data = "verkehrsdaten.txt";
    	char *Result = "feld.txt";
    
    	uniquePairs ( Data, Result );
    
    	return 0;
    }
    

    Gutes Gelingen.
    Gruß,
    B.B.



  • vielen Dank Big Brother ich werde es am Montag auspropieren..da es bei mir zu Hause nicht möglich ist.
    ich sage dir dann Bescheid, wenn soweit ist..
    Danke noch mal



  • Hallo Big Brother;
    habe das mit dem programm heute versucht was zu machen aber leider gibt mir keine fehler und erzeugt die datei feld nicht..weiss nicht wo das problem ist..



  • Keine Fehlermeldung, keine feld.txt ?
    Na, irgend etwas muss doch passieren. 😕



  • bis jetzt immer noch nicht wie gesagt die textdatei feld wird auch nicht ergeuzt.??? 😕



  • Von hier kann ich da auch nix machen. Schreib doch ein kleines Programm, das dir die verkehrsdaten.txt einliest und wieder ausgibt, dann hast du einen Ansatz und kannst ergänzen.



  • die textdatei feld wird jetzt erzeugt , aber nichts reingeschrieben also die bleibt leer??



  • Vielleicht gibt keine 'E' Zeile, die zu einer 'A' Zeile gehört, denn es werden nur Paare rausgefiltert.
    Habe es bei mir probeweise laufen lassen und es hat funktioniert.

    Ansonsten musst du dich mit einem Debugger vertraut machen, oder Zwischenausgaben einbauen und dir anzeigen lassen.



  • müssen die 'A' und 'E' zeile (paarweise) in der textdatei Verkehrsdaten in Reihenfolge kommen oder wie ?



  • azoul schrieb:

    müssen die 'A' und 'E' zeile (paarweise) in der textdatei Verkehrsdaten in Reihenfolge kommen oder wie ?

    Nö, die E-Zeile muss irgendwo unterhalb der A-Zeile auftauchen. Falls sie oberhalb gefunden werden soll, musst du den Dateizeiger an den Anfang setzen.



  • hallo B.B.
    das Programm springt nie in dieser if Anweisung rein?

    if ( 0 == strcmp ( A, B ))
                    { // Die zur A-Zeile zugeh�rige E-Zeile gefunden. 
                        A [0] = ANFANG;
                        addAB ( A, B, Result ); // Unikat-Paar hinzuf�gen. 
    
                        break; // Bricht die innere while-Schleife ab. 
                    }
    

    weisst du wo das problem liegt?



  • azoul schrieb:

    hallo B.B.
    das Programm springt nie in dieser if Anweisung rein?
    ...
    weisst du wo das problem liegt?

    Das ist gut möglich, das hängt von deiner Datei verkehrsdaten.txt ab.
    Angenommen, dort gibt es eine Zeile, die so aussieht:
    A 192.168.0.84 5996 192.168.0.221 5890 0 user0 usera

    Und irgendwo weiter unten gibt es eine Zeile, die so aussieht:
    E 192.168.0.84 5996 192.168.0.221 5890 0 user0 usera

    Dann springt das Programm da auch rein. Sobald sich die Zeile aber mehr als nur um den einen Buchstaben, das 'E' unterscheidet, wird dort auch nicht reingehüpft.



  • die datei verkehrsdaten sieht so aus: z.B

    A 192.168.0.84 6500 192.168.0.221 6380 0 user user1
    A 192.168.0.84 6500 192.168.0.221 6380 0 user user1
    A 192.168.0.84 6500 192.168.0.221 6380 0 user user1
    E 192.168.0.84 6500 192.168.0.221 6380 user user1
    A 192.168.0.123 5062 192.168.0.121 10014 8 user3 user4
    A 192.168.0.84 6502 192.168.0.221 6382 0 user user1
    A 192.168.0.84 6502 192.168.0.221 6382 0 user user1
    A 192.168.0.84 6502 192.168.0.221 6382 0 user user1
    E 192.168.0.84 6502 192.168.0.221 6382 user user1
    E 192.168.0.123 5062 192.168.0.121 10014 user3 user4
    

    warum funktioniert dann nicht, obwohl die E Zeile immer nach A Zeile kommt??


Anmelden zum Antworten