• Liebe User, bitte beachtet folgendes Thema: Was im Forum passiert, bleibt im Forum! Danke!
  • Hallo Gemeinde! Das Problem leidet zurzeit unter technischen Problemen. Wir sind da dran, aber das Zeitkontingent ist begrenzt. In der Zwischenzeit dürfte den meisten aufgefallen sein, dass das Erstellen von Posts funktioniert, auch wenn das Forum erstmal eine Fehlermeldung wirft. Um unseren Löschaufwand zu minimieren, bitten wir euch darum, nicht mehrmals auf 'Post Reply' zu klicken, da das zur Mehrfachposts führt. Grußworte.

C-Code zum Einlesen von Datein

Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Hi,

ich habe folgendes Problem:
Ich möchte aus einer Datei gewisse Sachen einlesen. Dazu dient der fscanf-Befehl. Jedoch sind diese Dateien nicht immer im gleichen Format, sprich es gibt eine unbestimmte Anzahl von Zeilen.

Die einzulesene Datei sieht in etwa so aus:
Code:
r_1     1
r_2     1
x_1_2   1
x_1_3   1
y_1_2   1
w_1_2   1

Dabei variiert die Anzahl der r, x, y, w Einträge. Ich benötige jedoch nur den letzen r Eintrag und alle w Einträge.
Bis jetzt habe ich das so gemacht, dass ich als Input den letzten r Eintrag mir besorgen (der ist bekannt) und dann sooft die r-Werte einlese und dann mit einer While Schleife
while (fscanf(dp2,"w_%d_%d ",&v2,&dummy1) != EOF)
Bis zum Ende gehe.

Nur kriege ich das nicht hin, sofern zwischen den r und w Variablen noch die x und y Variablen stehen. Ich weiß nie, wieviele da stehen, manchmal stehen da keine, manchmal mehrere.

Irgendwer eine Idee?
 
Mitglied seit
18.07.2001
Beiträge
2.152
Reaktionen
2
Ort
Nürnberg
was macht fscanf denn mit dem stream wenn das format nicht passt? bleibt die position unveraendert?

wenn ich mir die beispieldaten so anschaue wuerde ich instinktiv lieber zeilenweise einlesen und dann ein switch() auf den ersten character des strings machen.
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Nunja, in meiner while Schleife lese ich dann jeweils die w's und den Wert dahinter ein (der wird in nem dummy gespeichert, da er sowieso nur 1 oder 0 ist und sofern er 0 ist, wird die variable nicht angezeigt). So gelangt er dann ans Ende des Files.

Sonst bekam ich öfters endlos-schleifen zustanden :/
 

Jesus0815

Guest
Möchtest du nur einen Code der ganz Allgemein eine Datei einliest?

#include <cstdlib>
#include <string>
#include <iostream>

string Quelldateiname;
quelle.open(Quelldateiname.c_str(), ios::binary|ios::in);

Was du dann genau auslesen lassen willst kannst du ja mit deinen Schleifen realisieren. Oder hab ich dich nu missverstanden? Ich kann hier gerne noch schnell ein Beispiel zammschustern wenn du magst.

MfG
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Ist das nicht ein C++ Code?

Evtl. mag meine erste Beschreibung etwas verwirrend sein.
Ich möchte im Grunde nur die w-Variablen auslesen, jedoch weiß ich nie, an welcher Stelle die sich befinden. Davor gibt es entweder x-,y- oder eben die r-Variablen.

Bis zum Ende auslesen klappt ohne Probleme, jedoch weiß ich nicht genau, wie ich solange die Datei durchforste, bis z.b. ein "w" am Anfang der Zeile steht.
 

Jesus0815

Guest
Jo, das isn C++-Code. Du brauchst ja was für C, sry jetzt erst gemerkt.

Möchtest du das am Ende ausgegeben wird wieviele 'w' (char?) in der Datei enthalten sind? Ich finds grad etwas verwirrend. Wenn w eine Variable ist, dann wäre doch xyw eine andere und dann nicht mehr relevant? Ich glaub ich steh grad aufm Schlauch :confused:
 
Mitglied seit
12.08.2002
Beiträge
12.549
Reaktionen
0
er will keinen programmcode sondern eine strukturierte logik.

da er jedoch nicht klarzustellen vermag, ob w beispielsweise eineindeutig ist oder aber vielleicht sogar generell in der letzten zeile steht wird es schwer, ihm dabei zu helfen ~

ich vermute, dass er schlichtweg keine richtige verschachtelung kennt.
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Original geschrieben von TE)Kain
Jo, das isn C++-Code. Du brauchst ja was für C, sry jetzt erst gemerkt.

Möchtest du das am Ende ausgegeben wird wieviele 'w' (char?) in der Datei enthalten sind? Ich finds grad etwas verwirrend. Wenn w eine Variable ist, dann wäre doch xyw eine andere und dann nicht mehr relevant? Ich glaub ich steh grad aufm Schlauch :confused:

Also, die x,y,w Variablen sind Lösugen aus einem externen LP-Solver (CPLEX, falls er dir etwas sagt). Diese Variablen haben die jeweils die Form x_1_2,x_2_3, w_1_2,w_2_4,etc etc.

Die Zahlen hinter den w's brauche ich nur, die anderen sind nicht von Bedeutung.
Die W-Variablen sind immer am Ende, dahinter kommt nix mehr. Mir war so, als hätte ich das irgendwo geschrieben....
 
Mitglied seit
12.08.2002
Beiträge
12.549
Reaktionen
0
ich kann "deine" sprache nicht, aber rein logisch ist da doch kein problem, da muß man doch noch nichtmals was verschachteln; was spricht denn aus deiner sicht gegen zeilenweise einlesen, vielleicht sogar von hinten?
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Tja, ich kriege das nicht hin, von unten Anzufangen. Auch weiß ich nicht, wie ich es beschreiben soll, dass er solange die Zeilen einließt, bis ein w am Anfang erscheint.

Im Pseudocode kriege ich das halbwegs hin, nur "technisch" klappt nix.

Code:
-Lese Zeile solange bis was anderes als "r" vorne steht
-Speichere die Zahl vom letzten r_zahl
-Geh weiter bis ein w vorne steht
-Speichere die Zahlen bis EOF erreicht ist.

Wüsste ich, wieviele Zeilen in Schritt 1 und 3 sind, so kriege ich das hin (sieht unschön aus, aber funktioniert), aber diese Anzahl varriert immer.

Z.b. Bräuchte ich aus meinem Code vom ersten Post nur folgendes zu wissen:

Die maximale Anzahl der r's ist 2 und bei w steht 1 und 2.
 
Mitglied seit
09.11.2002
Beiträge
880
Reaktionen
0
Zunächst weiß ich nicht, warum Du nicht einfach Zeilenweise einliest und solange der erste char nicht ein 'w' ist den buffer einfach verwirfst?
Alternativ kannst Du unter Linux auch vom Standardinput lesen und Deine Datei mittels tac an Dein Programm pipen. tac gibt die Datei verkehrtherum aus (cat <-> tac).
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Ich will das ja zeilenweise einlesen, nur weiß ich nicht wie das geht, sofern da irgendetwas steht. Mir fehlt quasi ein Abbruchkriterium!!!

Genau das, was du im ersten Satz fragst, versuche ich und kriege es nicht hin.
 
Mitglied seit
09.11.2002
Beiträge
880
Reaktionen
0
Code:
#include <stdlib.h>
#include <stdio.h>

int main() {

	FILE *datei;
	char buffer[100];
	datei = fopen("abc.txt", "r");
	if (datei == NULL) {
		printf("\nDatei abc.txt kann nicht geöffent werden\n");
		exit(-1);
	}

	int zeilen = 0;
	int w_counter = 0;
	while (!feof(datei)) {
		zeilen++;
		if (fgets(buffer, 99, datei) == NULL) {
			printf("Konnte Zeile %d nicht lesen\n",zeilen);
		} else {
			if (buffer[0] == 'w') {
				w_counter++;
				/* here do something with buffer */
			}
		}
	}
	printf("\n\nFazit:\nZeilen gelesen: %d\n",zeilen);
	printf("%d x 'w' am Anfang gefunden.\n",zeilen);
	fclose (datei);
}


Funktiniert bei mir soweit. Allerdings noch nicht optimal, er liest immer eine Zeile zuviel ein und bringt dann den Fehler "Konnte Zeile nicht lesen".
Außerdem macht er Probleme, wenn der buffer zu klein ist.

Edit:
Beschreibung von fgets: http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html

Edit2:
So wie ich das sehe mußt Du nach dem Test (fgets(buffer, 99, datei) == NULL) noch einen Test auf EoF machen, dann sollte das mit dem letzte leere Zeile einlesen kein Problem mehr sein:
Code:
	while (fgets(buffer, 99, datei) != NULL && !feof(datei)) {
		zeilen++;
		if (buffer[0] == 'w') {
			w_counter++;
			/* here do something with buffer */
		}
	}
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Schonmal vielen Dank, soetwas in der Art hatte ich gesucht!!!

Werde es am Montag direkt an der Uni mal testen.

Auch danke an den anderen für ihre Bemühungen.
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
So, ich bins mal wieder.

Es funktioniert soweit so gut.
Dennoch ist ein kleiner Fehler aufgetreten. Es wird immer die erste Zeile mit den W-Einträgen nicht gelesen.

Mein Code sieht derzeitig wie folgt aus:
Code:
optimalloesung=0;
	while (feof(dp2) == 0) 
	{
		printf("TEST\n");
		if (fgets(buffer, 99, dp2) == NULL && feof(dp2) == 0) 
		{
			printf("Konnte Zeilen nicht lesen\n");
		} 
		else 
		{
			if (buffer[0] == 'r') 
				optimalloesung++;
			if (buffer[0] == 'w')
			{
				while (fscanf(dp2,"w_%d_%d_%d ",&v1,&v2,&dummy1) != EOF)  

				{
				fscanf(dp2,"w_%d_%d_%d ",&v1,&v2,&dummy1);
				fscanf(dp2,"%lf ",&dummy2);

				LoesungMat[v1][v2]=1;
				printf("w gefunden:%d %d\n",v1,v2);
				}
			}
		}	
	}

Die einzulesende Datei wäre
Code:
r_1                           1.000000
x_0_2_1                       1.000000
x_1_5_1                       1.000000
x_2_7_1                       1.000000
x_3_4_1                       1.000000
x_4_6_1                       1.000000
x_5_0_1                       1.000000
x_6_1_1                       1.000000
x_7_3_1                       1.000000
y_1_1                         1.000000
w_0_2_1                       1.000000
w_1_5_1                       1.000000
w_2_7_1                       1.000000
w_3_4_1                       1.000000
w_4_6_1                       1.000000
w_5_0_1                       1.000000
w_6_1_1                       1.000000
w_7_3_1                       1.000000

Und als Ausgabe bekomme ich ("Test" weggelassen):
Code:
w gefunden:1 5
w gefunden:2 7
w gefunden:3 4
w gefunden:4 6
w gefunden:5 0
w gefunden:6 1
w gefunden:7 3
Optimalloesung ist: 1

Wie man sieht, fehlen die 0 2 Einträge.

Woran das liegt, verstehe ich auch, da ich mit fgetc() die Zeile einlesen überspringt er wegen dem fscanf() genau die eine Zeile. Nun könnte ich den Buffer ja durchforsten, jedoch ist nicht immer garantiert, dass die Zahlen nach dem w immer nur eine Stelle haben und somit wäre es theoretisch möglich, jedoch eine ziemliche Friemelei. Jemand nun eine Idee, wie ich das umgehen kann? Gleich am Anfang mit fscanf() arbeiten?
 
Mitglied seit
13.04.2002
Beiträge
747
Reaktionen
0
Ort
Braunschweig
Ahhh vielen Dank!!!. Damit gehts, nur ließt er jetzt die letzte w-Zeile zweimal ein.

*edit*
Habs nun gepackt:

Code:
dp2=fopen(argv[2],"r");
	optimalloesung=0;
	while (feof(dp2) == 0) 
	{
		if (fgets(buffer, 99, dp2) == NULL && feof(dp2) == 0)
		{
			printf("Konnte Zeilen nicht lesen\n");
		} 
		else 
		{		
			if (buffer[0] == 'r') 
				optimalloesung++;
			if (buffer[0] == 'w' && feof(dp2) == 0)
			{
				sscanf(buffer,"w_%d_%d_%d ",&v1,&v2,&dummy1);

				LoesungMat[v1][v2]=1;
				printf("w gefunden:%d %d\n",v1,v2);
			}
		}	
	}
	printf("Optimalloesung ist: %d\n",optimalloesung);
 
Oben