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 geladenDas 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