Datei Zeile für Zeile auslesen

Ich habe das Programm nicht ausprobiert, sondern sage erstmal einige Fehler, die mir auf den ersten Blick ins Auge stechen.

Du definierst:

Code:
char *string[10];

Das ist kein String, sondern ein Array von 10 Zeigern auf Strings. Ein String ist das hier:

Code:
char *string ;

Desweiteren dereferenzierst du die Variable überall, Beispiel:

Code:
//fgets(*string, 8, stream ) ;

Der Ausdruck *string zeigt auf nicht initialisierten Speicher. fgets() kann nicht mit einem Zeiger auf einen String funktionieren, der im Speicher überhaupt nicht existiert. Das bedeutet: Wenn man einen String als char* definiert, ist zu diesem Zeitpunkt noch kein Speicher für diesen String reserviert. Dies geschieht erst bei einer Zuweisung. fgets() aber reserviert nicht selbst Speicher, sondern erwartet einen Zeiger auf einen bereits reservierten Speicherbereich. Übergibt man ihm einen char*, so schreibt fgets() seine Daten an irgendeine zufällige Stelle im Speicher, auf die der char* gerade zeigt, was einen Zugriffsfehler verursacht. Folgendermaßen wäre es korrekt:

Code:
char string[1024] ;
// blablabla
fgets( string, sizeof( string ), stream ) ;

Der fscanf-Befehl wird zwar korrekt angewandt, allerdings ist x ein Zeiger auf einen double, der fscanf-Befehl möchte jedoch gerne einen float.

Versuch mal, die genannten Fehler da rauszukriegen.

Gawayn
 
Zuletzt bearbeitet:
Danke Gawayn für deine schnelle und ausführliche Hilfe!
Der Fehler lag wirklich an der falschen Deklaration des strings! Die Parameterübergabe bei den Funktionen klappt so wie ichs habe!
 
Ich hab mal noch ne Frage: Wie kann ich mein Programm geschickt umändern, damit ich keine Array mit ner speziellen Größe verwenden muss, sondern dass alles variabel ist?
 
Du hast 2 Möglichkeiten: a) Du verwendest eine verkettete Liste, oder b) du stellst als erstes die Größe der Datei fest und allokierst dann soviel Speicher, wie du brauchst.

Eine verkettete Liste ist z.B. folgende Struktur:

Code:
struct ENTRY {
  int data ;
  ENTRY *next ;
} ;

Du siehst, die Struktur ENTRY enthält einen Zeiger, der auf eine weitere ENTRY-Struktur zeigt. Indem man nun eine solche Struktur dynamisch allokiert und sich deren Adresse merkt, kann man nun anhand der next-Zeiger immer mehr solcher Strukturen erzeugen. So entsteht eine Liste, deren Daten im Speicher über die next-Zeiger verkettet sind.

Einfacher wäre es, wenn du am Beginn des Programms die Größe der Datei feststellst und dann einen Speicherbereich allokierst, der groß genug ist, die Daten aufzunehmen. Diesen Speicherbereich sprichst du anschließend als Array an.

Gawayn
 
zu a)
Das mit der verketteten Struktur hat mir schon ein Kumpel geraten! Kannst du mir ein kurzes Beispiel geben? Ich blick da noch nicht so ganz durch.

zu b)
Die Größe der Datei hab ich schon ausgelesen. Ich müsste doch dann einfach noch mit malloc Speicher allocieren und damit die Feldgröße bestimmen, oder?

PS: Die Lösung mit der verketteten Struktur wäre mir lieber.
 
Wenn du ein Array allokieren willst, musst du die Anzahl der Zeilen in der Textdatei ermitteln, weil ja in jeder Zeile genau eine Zahl steht. Das ergibt dann die Größe deines Arrays. Dazu muss man nicht malloc nehmen, der new-Operator tuts auch:
Code:
float *a ;
a = new float[ANZAHL] ;
a[0] = 1.9 ;
// und so weiter
Eine verkettete Liste kann man nicht "kurz" programmieren, da diese Struktur schon etwas mehr Hirnarbeit erfordert, will heißen, da kommt etwas mehr Code zusammen. Schließlich muss die Liste "verwaltet" werden. Es genügt nicht, der Liste Einträge hinzuzufügen. Man muss sie auch abrufen (suchen) und löschen können. Deswegen wird der Code länger. Der folgende Code erstellt drei Einträge. Der Wert NULL im next-Zeiger markiert das Ende der Liste.
Code:
ENTRY *start = new ENTRY ;

start->data = blablabla ;
start->next = new ENTRY ;
start->next->data = blublublu ;
start->next->next = new ENTRY ;
start->next->next->data = blobloblo ;
start->next->next->next = NULL ;
Um das Ganze nun dynamisch im Programm zu verwalten, am besten noch in einer eigenen Klasse, musst du mit einem Laufzeiger, dem du am Anfang den Wert von start zuweist, durch die Liste rutschen. So kannst du Einträge suchen oder löschen. Mach was draus :)

Gawayn
 
Dank dir.

Habs trotzdem erstmal mit dem allokierten Feld gemacht! Ging recht fix!
Das mit der verketteten Liste muss ich mir nochmal anschauen.

MFG

Andy
 
Zum Thema einfach und doppelt verkettete Listen gibt es hier im Forum einige Threads, einfach mal die Suche benutzen.

Gruß Homer
 
Wenn auch C++ geht, verwende ich es immer.

Daher:

Code:
std::ifstream ifs;
ifs.open("foo.txt");

while ( ! ifs.eof() ) {
	std::string aLine;
	std::getline(ifs, aLine);
	std::istringstream is(aLine);
	double d;
	is >> d;

	// hier ist das double aus der n-ten Zeile fertig...

}

ifs.close();
 
Hi,
das, was hier für strings in double beschrieben wurde, hätte ichgerne für eine selbstdefinierte Klasse:
Code:
class Vector
{
public:
	Vector(); 																		
	Vector(GLfloat x1,GLfloat y1,GLfloat z1): x(x1),y(y1),z(z1) {}; 
	~Vector();
	 
	
	void SetComp(GLfloat x_, GLfloat y_, GLfloat z_)
    {
		x=x_;
		y=y_; 
		z=z_; 
    }
	GLfloat x, y, z;
};

Vector::Vector(): 
	x(0),y(0),z(0) {}

Vector::~Vector() {}

Ich will die Vektoren in einer datei speichern und später auslesen...
Dazu hatte ich folgende Idee: ich speichere die Addressen der Zeiger, die ich mit
Code:
	Vector** Punkt = new Vector*[zeilen_anzahl];		//Zeiger auf Arrays von Zeigern [auf Vector], auf heap

		for (int i = 0; i< zeilen_anzahl; i++)
			Punkt[i] = new Vector[spalten_anzahl];
deklariert habe:
Code:
		for (int i=0; i<=maxSchritt; i++)
			for (int j=0; j<=maxSchritt; j++)
			{
				Punkt[i][j].x = j*15.0/(maxSchritt+1)-2.5; //xWerte berechnen
				Punkt[i][j].z = i*15.0/(maxSchritt+1)-5.0;
				f.write((char*) &Punkt[i][j],  sizeof Punkt[i][j]);
				f.write("\n", 2);
			}
Also ich meine zumindest, dass der mit (char*) &Punkt[i][j] das macht.
Ich habe allerdings keine ahnung, wie ich die Vektoren wieder auslese,
am liebsten wär mir eben, dass ich aus der Datei die Addressen des Punktarrays auf dem heap auslese...

mfg Schorsch
 

Neue Beiträge

Zurück