Textdatei einlesen

stu_csn

Grünschnabel
Hallo,
ich versuche mich seit einer Woche mit Visual C++. Bin also noch blutiger Anfänger.
Im Moment versuche ich folgendes Problem zu lösen.
Ich habe ein e große Textdatei, die folgendermaßen aufgebaut ist.
In der ersten Zeile steht X Y und dann Zahlen mit führenden Nullen von 1 bis n( Bildnummern)
Danach folgen Zeilen mit in Spalte 1 und 2 die x und Y Koordinaten und dann Gleitkommazahlen.
Alle durch Tab getrennt.

Ziel der Anwendung soll es sein n Dateien zu erzeugen, die für jedes Bild die Gleitkommazahlen in Zeilen und Spalten sortiert, also
y x->
| z(xy)
V

Dabei habe ich mir gedacht, das ich die Input-Datei erstmal zeilenweise in ein mehrdimensionales Array einlese, da die Koordinaten sortiert sind, sollte die Ausgabe dann relativ einfach sein, denke ich.
Ich hab aber da massive Verständnisprobleme, also hab ich es erstmal mit char Probiert.
Die Anzahl der Zeilen und Spalten wird in dem Beispiel schon richtig ausgelesen, aber in z.B. Feld[0] steht völliger quatsch und in allen Feld[ i i>0 steht immer die letzte Zeile.
Kann mir jemand erklären warum? Und wie es richtig währe. Im Idealfall.
Code:
#define MAXLEN 60
#define MAXZEIL 10
#define MAXSPALT 10
int i;
int j;
FILE * fp = fopen(m_sInput,"r"); 
char buf[ MAXLEN ] = { 0 };
char seps[] = "\t\n";
char* token;

char * (*Feld)[MAXSPALT];
Feld = new char *[MAXZEIL][MAXSPALT];

i=0;
while( fgets( buf, MAXLEN, fp ) != NULL ) 
{ 
j=0; //Spalten
        token=strtok(buf,seps);
		while (token != NULL)
		{
        Feld[i][j]=token;
		j++;

        token=strtok(NULL,seps);
		}

	//fprintf( stdout, "%s" , buf ); 
	i++;

} 
m_FileSize.Format("%i",i);
m_sSpalten.Format("%i",j);
m_sdx.Format("%s",Feld[0][5]);
UpdateData(FALSE);
fclose( fp );
 
Zuletzt bearbeitet:
Du möchtest die Datei zeilenweise in ein 2 dimensionales Array einlesen?
Ok, zunächst deklarierst du das Array falsch. Du brauchst für jede Zeile ein char Array, also dynamisch einen Zeiger auf das erste Element (char*). Dann müssen diese Zeiger in ein Array, wieder dynamisch.
Code:
char **Feld = new char* [MAXZEIL]

An dieser Stelle ist es noch nicht sinnvoll eine Zeilenlänge festzulegen, da die durchaus variieren kann und wenn wir schon dynamisch unseren Speicher reservieren, dann brauchen wir den ja nicht sinnlos verbraten.

Jetzt wird jede Zeile eingelesen. Du wirst dir sicher was dabei gedacht haben, MAXLEN auf 60 zu setzen, also arbeite ich auch damit.
Code:
int num = 0;
char buf[MAXLEN];

while ((num < MAXZEIL) && (fgets(buf, MAXLEN, fp)))
{
  if (buf[strlen(buf)-1] == 0x0A) buf[strlen(buf)-1] = 0;
  Feld[num] = new char[strlen(buf)];
  strcpy(Feld[num++],buf);
}

Die Zeilen der Datei sind jetzt im Array.
Zum Ausgeben:
Code:
for (int i = 0; i < num; i++) std::cout << Feld[i] << "\n";

Oder schreibe ich hier am Thema vorbei :rolleyes: ?

Ach ja, den Speicher hinterher wieder freigeben:
Code:
for (int i = 0; i < num; i++) delete [ ] Feld[i];
delete [ ] Feld;
 
Danke erstmal für die Antwort.
Hat mir weitergehlfen, obwohl es nicht ganz das ist was ich brauche.
Brauche eigentlich nihct die ganze Zeile sondern die einzelnen Werte in nem 2D Array. aber jetzt hab ich ja nen funktionstüchtigen Ansatz, bei dem ich seh wie es gehen könnte.
Die Consts MAXZEIL, MAXLEN udn MAXSPALT brauchte ich um die Länge des Array zu definieren, weil meine Versuche immer in nem Stack overflow endeten, wenn ich die OrginalDatei nutzte. In der Praxis ist die Input Datei bis zu 1000 Spalten und 10000 Zeilen groß und wie gesagt voller Gleitkomma Zahlen.

Ich versuch mich erstmal an der Lösung mit char.
Und poste mal das Ergebnis oder ne neue Frage :-)

MfG stu_csn
 
Dann kannst du genauso vorgehen, nur dass du ein solches Array erst gar nicht erstellst. Du reservierst dir mit new einen großen char Puffer, ließt da eine Zeile rein und verarbeitest den Puffer sofort in dem du deine float Werte rausliest. Dann liest du die nächste Zeile ein.
 
Hallo nochmal,
hab eine weile gebraucht, aber hier ist die versprochene Lösung meines Problems.
Kann mir sicher vorstellen, das es viel zu vereinfachen gibt, aber es erstmal :-). Zumindest meine Beispieldatei, von 30 MB wird scheinbar richtig eingelesen
Jetzt gehts ans verarbeiten.

Code:
FILE * fp = fopen(m_sInput,"r"); 

int num=0;
#define x 800								//Spalten
#define y 7000								//Zeilen
char buf[x*10];								//Maximale Anzahl der Zeichen in einer Zeile
char seps[] = "\t\n";						//seperator für die Trennung der Spalten
int koor_x[y];								//Erste Spalte Koordinate X des Punktes
int koor_y[y];								//Zweite Spalte Koordinate Y des Punktes
int Bild[x];									//Bildnummer
int i=0;									//Laufvariable
int j=0;									//Laufvariable
char* token;								//Fliesskommazahl
double testvar=0;
float (*Feld)[x] = new float [y][x];		// Feld der Fliesskommazahlen


i=0;
while ((num < y) && (fgets(buf, x*10, fp)))
{
  j=0; 
  token=strtok(buf,seps);
  while (token != NULL)
  {
    if (i>0)
	{
	  if (j>1) 
	  {	
		  for (int n=0; n<strlen(token); n++)   {    if (token[n] == ',') token[n] = '.'; }
		  Feld[i][j]=strtod(token,NULL);
	  }
	  else
	  {
          if (j==0) {koor_x[i]=atoi(token);}
          if (j==1) {koor_y[i]=atoi(token);}
	  }
	}
	else
	{
	  if (j>1) 
	  {	
		  Bild[j]=atoi(token);
	  }

	}
    token=strtok(NULL,seps);
    j++;
  }
  i++;
  num++;
}

UpdateData(FALSE);
fclose( fp );

Danke nochmal für die Hilfe und wenn jemanden etwas auffält immer her damit.
Ich hab gerade erst anfgefangen C++ zu verstehen.

MfG stu
 
Textdatei einlesen -- C++ Quelltext Zeilennummern entfernen

Hallo habe da ein problem, ich bin dabei meine kenntnisse in c++ zu erweitern.dazu benutze ich das c++ in 21 tagen buch. mit der zeit nerven die zeilennummern die man jedesmal von hand entfernen muss um den quellcode zu benutzen. ich habe schon ein programm geschrieben mit dem man EIN zeichen weg bekommt. aber damit bekommt man keine fortlaufenden zahlen weg. ich habe schon viel gegooglt aber nix passendes gefunden.ich bitte um untersützung, mfg hier ein auszug aus dem quellcode:
Code:
Einlesen.get(Zeichen);
  while (Einlesen.good())
  {
    
    if (Zeichen==':') Zeichen='\n';  
    Ausgeben.put(Zeichen);
    Einlesen.get(Zeichen);

  }
 
Zurück