Einlesen einer Datei in dynamisches Feld



  • Liebe C-Fans,

    mein Messprogramm erzeugt mir folgende Ausgabedatei:

    #Step (fs)  Delay stage (um)  Mitutoyo (um)  Ch1        Ch2        Ch3        Ch4        Ch5        Ch6        Ch7
     -200.000        29.656            -94       641        445        535        584        616        628        136
    

    mit einer, je nach Messung, unterschiedlichen Zeilenanzahl. Ziel ist es, diese Datei zur weiteren Verarbeitung in ein Dynamisches Feld/Array einzulesen. Dazu habe ich folgendes Programm geschrieben:

    //#include "stdafx.h"
    #include "stdlib.h"
    #include "stdio.h"
    
    int main(int argc, char* argv[])
    {
    	int i;
    	int nPosition=0;
    	int nSpace=0;
    	int nNoOfLines=0;
    	int nTotalNoOfLines=0;
    	FILE *stream;
    	char line[200];
    	double **ptr;
    
    	// determine the total number of lines
    	if( (stream = fopen( "m012.2pe", "r" )) != NULL )
    	{
    	   while( fgets( line, 199, stream ) != NULL){
    		   if( line[0]=='#') continue;
    		   nNoOfLines++;
    	   }
    
    	}
    	printf( "%d",nNoOfLines);
    
    	fseek(stream,0,SEEK_SET);
    	nTotalNoOfLines=nNoOfLines;
    
    	//allocate memory
    	ptr = (double**)malloc(sizeof(double*)*(nNoOfLines));
    	for( i=0; i<10; i++){
    	   ptr[i] = (double*)malloc(sizeof(double)*(nNoOfLines+1));
    	   if( ptr[i]==NULL){
    		   printf("Error: Could not allocate memory!\n");
    		   return(1);
    	   }
    	}
    
    	nNoOfLines=0;
    
    	//read the filedata into the array
    	while( fgets( line, 199, stream ) != NULL){
    	   if( line[0]=='#') continue;
    	   for( i=0; i<10;i++){
    		   printf("%d",i);
    		   if( sscanf(line+nPosition,"%lf %n",&ptr[i][nNoOfLines],&nSpace) != 1){
    			   printf("Error during reading at line %d\n",nNoOfLines);
    			   return (1);
    		   }
    		   nPosition += nSpace;
    	   }
    	   nNoOfLines++;
    	}
    
    	fclose( stream );   
    
    	return (0);
    }
    

    Das Programm läßt sich nicht ausführen, da es beim Befehl

    sscanf
    

    Speicherverletzungsprobleme gibt. Als Compilierer verwende ich Visual Studio 6.0 (dürfte aber trotzdem reiner C-code sein).

    Ich würde mich riesig feruen, wenn mir jemand sagen könnte, was ich falsch mache.

    Schon mal vielen Dank im voraus und Gruß
    Daniel



  • Hmm, eventuell könnte es helfen, "nPosition" wieder auf 0 zurückzusetzen, bevor du mit einer neuen Textzeile anfängst (sprich: vor der "for(i=0;i<10;i++)"-Schleife).



  • Danke für Deine Antwort, leider hilft das aber nicht.

    Gruß
    Daniel



  • *genauer hinsieht*
    Wie hast du auch dein Array zusammengebaut? Du reservierst Platz für n Zeilen mit je n+1 Elementen und versuchst dann in Zeile 0 bis 10 jeweils das Element i (=aktuelle Zeile) zu schreiben. (btw, beim sscanf scheinst du auch die Indizes vertauscht zu haben)

    //korrekte Speichervergabe:
    ptr = malloc(nOfLines*sizeof(double*));
    for(i=0;i<nOfLines)
      ptr[i] = malloc(10*sizeof(double));
    
    nNoOfLines=0;
    
    while( fgets( line, 199, stream ) != NULL){
      if( line[0]=='#') continue;
      nPosition=0;
      for( i=0; i<10;i++){
        if( sscanf(line+nPosition,"%lf %n",&ptr[nNoOfLines][i],&nSpace) != 1){
          printf("Error during reading at line %d\n",nNoOfLines);
          return 1;
        }
        nPosition += nSpace;
      }
      nNoOfLines++;
    }
    

    PS: Daß du deinen Speicher auch wieder freigeben solltest, ist dir hoffentlich klar, oder?



  • Danke!

    Bei dem was Du geschrieben hast liefert mir der Compiler in Deiner Zeile 2 folgenden Fehler:

    cannot convert from 'void *' to 'double ** '
    

    ??????

    Speicher freigegen wußte ich nicht. Mache ich aber noch (realloc).

    Gruß und Mahlzeit
    Daniel



  • Sorry, ich war bisher immer der Meinung, void* kann in jeden Zeigertyp konvertiert werden - aber offenbar ist dein Compiler etwas empfindlicher damit 😃 (zur Lösung solltest du doch explizit nach double** bzw. double* casten).

    PS: Für die Speicherfreigabe ist übrigens free() zuständig 😉



  • das ganze hilft leider nichts. Es läßt sich zwar mit 0 Fehlern und 0 Warnungen kompilieren, aber bei Programm starten, kommen lauter Fehlermeldungen wie:

    runtime error R6002
    floating point not loaded
    

    Also mein Programm sieht momantan so aus:

    #include "stdlib.h"
    #include "stdio.h"
    
    int main(int argc, char* argv[])
    {
    	int i;
    	int nPosition=0;
    	int nSpace=0;
    	int nNoOfLines=0;
    	int nTotalNoOfLines=0;
    	FILE *stream;
    	char line[200];
    	double **ptr;
    
    	// determine the total number of lines
    	if( (stream = fopen( "m012.2pe", "r" )) != NULL )
    	{
    	   while( fgets( line, 199, stream ) != NULL){
    		   if( line[0]=='#') continue;
    		   nNoOfLines++;
    	   }
    
    	}
    	printf( "%d",nNoOfLines);
    
    	fseek(stream,0,SEEK_SET);
    	nTotalNoOfLines=nNoOfLines;
    
    	//allocate memory
    	ptr = (double**)malloc(nNoOfLines*sizeof(double*));
    	for(i=0;i<nNoOfLines;i++){
    		ptr[i] = (double*)malloc(10*sizeof(double));
    	}
    
    	nNoOfLines=0;
    
    	//read data from file into array
    	while( fgets( line, 199, stream ) != NULL){
    		if( line[0]=='#') continue;
    		 nPosition=0;
    		for( i=0; i<10;i++){
    		 if( sscanf(line+nPosition,"%lf %n",&ptr[nNoOfLines][i],&nSpace) != 1){
          printf("Error during reading at line %d\n",nNoOfLines);
          return 1;
    		 }
    	 nPosition += nSpace;
    	 }
    	nNoOfLines++;
    	}
    
    	if(ptr!=NULL)
    	{
    		free(ptr);
    		ptr=NULL;
    	}
    
    	fclose( stream );   
    
    	return (0);
    }
    


  • Mein MSDN liefert zu R6002:

    C-Laufzeitfehler R6002
    Gleitkommaunterstützung nicht geladen

    Das Programm benötigt die Gleitkommabibliothek. Diese war jedoch nicht in das Programm eingebunden.

    Mögliche Ursachen sind:
    [list][]Das Programm wurde mit einem Schalter (wie z. B. /FPi87), der einen Coprozessor erfordert, kompiliert bzw. verknüpft. Sie haben das Programm auf einem Computer ausgeführt, auf dem kein Coprozessor installiert ist.
    [
    ]Eine Formatzeichenfolge für eine printf- oder scanf-Funktion enthält die Angabe eines Gleitkommaformats, das Programm enthielt jedoch keinerlei Gleitkommawerte bzw. -variablen.
    []Der Compiler minimiert die Größe eines Programms, indem er die Gleitkommaunterstützung nur bei Bedarf lädt. Der Compiler kann keine Gleitkommaformate in Formatzeichenfolgen finden und hat daher die notwendigen Gleitkommaroutinen nicht geladen.
    [
    ]Verwenden Sie ein Gleitkommaargument für das angegebene Gleitkommaformat, oder führen Sie an beliebiger Stelle im Programm eine Gleitkommazuweisung durch. Hierdurch wird der Compiler angewiesen, die Gleitkommaunterstützung zu laden.
    [*]In einem gemischtsprachigen Programm wurde beim Binden des Programms eine C-Bibliothek vor einer FORTRAN-Bibliothek angegeben. Geben Sie die C-Bibliothek an letzter Stelle an, und binden Sie das Programm erneut.

    Vielleicht hilft etwas davon weiter.

    (Notfalls kannst du auch versuchen, das Programm in "Gleitkomma-Modus" zu setzen, indem du irgendwo eine float-Funktion verwendest (z.B. aus der <math.h>)



  • ES GEHT!!! Wunderbar! Vielen herzlichen Dank für Deine große Mühe!

    Beste Grüße
    Daniel


Anmelden zum Antworten