StarCraft 2 Forum | inStarCraft.de by ingame™  
Alt 07. März 2008, 09:16   #1
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
C-Code zum Einlesen von Datein

Advertising
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?
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 11:53   #2
ViperDK
 
Benutzerbild von ViperDK
Archon
 
Registriert seit: Jul 2001
Ort: Nürnberg
BNet-Account: ViperDK
BNet2-Account: ViperDK
Beiträge: 2.017
ViperDK eine Nachricht über ICQ schicken
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.
ViperDK ist offline  
Mit Zitat antworten
Alt 07. März 2008, 12:05   #3
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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 :/
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 13:33   #4
Jesus0815
 
Beiträge: n/a
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
 
Mit Zitat antworten
Alt 07. März 2008, 13:58   #5
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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.
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 14:14   #6
Jesus0815
 
Beiträge: n/a
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
 
Mit Zitat antworten
Alt 07. März 2008, 14:33   #7
aMrio
 
Benutzerbild von aMrio
Postmaniac Silber
 
Registriert seit: Aug 2002
Beiträge: 12.551
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.
__________________
Zitat:
Original geschrieben von DoOfNusS
thx @ hässlichen post lösch wichtel.
nutzt eure idlezeiten
aMrio ist offline  
Mit Zitat antworten
Alt 07. März 2008, 14:37   #8
Jesus0815
 
Beiträge: n/a
Sei nicht so gemein
 
Mit Zitat antworten
Alt 07. März 2008, 14:43   #9
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
Zitat:
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
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....
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 14:48   #10
Jesus0815
 
Beiträge: n/a
Ui, ja, hm... Das ist schon sehr speziell.

Probiers mal hier: http://www.cplusplus.com/
Ist zwar ein englischsprachiges Forum, dafür sind die Leute die da rumgurken richtige cracks.

Alternativ hier: http://www.c-plusplus.de/cms/
 
Mit Zitat antworten
Alt 07. März 2008, 14:54   #11
aMrio
 
Benutzerbild von aMrio
Postmaniac Silber
 
Registriert seit: Aug 2002
Beiträge: 12.551
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?
__________________
Zitat:
Original geschrieben von DoOfNusS
thx @ hässlichen post lösch wichtel.
nutzt eure idlezeiten
aMrio ist offline  
Mit Zitat antworten
Alt 07. März 2008, 15:08   #12
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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.
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 16:04   #13
Meta123Tron
 
Benutzerbild von Meta123Tron
Räuber
 
Registriert seit: Nov 2002
Beiträge: 880
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).
Meta123Tron ist offline  
Mit Zitat antworten
Alt 07. März 2008, 16:11   #14
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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.
Cleese ist offline  
Mit Zitat antworten
Alt 07. März 2008, 16:30   #15
Meta123Tron
 
Benutzerbild von Meta123Tron
Räuber
 
Registriert seit: Nov 2002
Beiträge: 880
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/...ons/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 */
		}
	}
Meta123Tron ist offline  
Mit Zitat antworten
Alt 07. März 2008, 23:05   #16
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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.
Cleese ist offline  
Mit Zitat antworten
Alt 10. März 2008, 10:53   #17
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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?
Cleese ist offline  
Mit Zitat antworten
Alt 10. März 2008, 11:35   #18
Meta123Tron
 
Benutzerbild von Meta123Tron
Räuber
 
Registriert seit: Nov 2002
Beiträge: 880
Du liest also _nachdem_ das erste 'w' gefunden wurde die Datei weiter mit fscanf aus? Klar, die erste Zeile in Buffer verwirft er dann.
Ich würde daher weiter fgets() verwenden, und wenn buffer[0]=='w', dann würde ich mit sscanf den _buffer_ auslesen.
http://www.cplusplus.com/reference/c...io/sscanf.html
Meta123Tron ist offline  
Mit Zitat antworten
Alt 10. März 2008, 11:58   #19
Cleese
 
Benutzerbild von Cleese
Belagerungspanzer (Panzermodus)
 
Registriert seit: Apr 2002
Ort: Braunschweig
Beiträge: 745
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);
Cleese ist offline  
Mit Zitat antworten
Antwort
Zurück   StarCraft 2 Forum | inStarCraft.de by ingame™ > Support Foren > Technik/Software-Forum

Themen-Optionen
Ansicht

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.

Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:39 Uhr.


Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.


ingame Netzwerk
Support | AGB | Probleme mit der Werbung melden
Online Werbung | Mediadaten | Unternehmen | Karriere | Presse | Impressum

© ingame GmbH, ingame™, in™ und incup™ sind eingetragene Markenzeichen der ingame GmbH. Verwendung von Inhalten nur mit schriftlicher Genehmigung.