Zeile einer Matrix schreiben in einem Rutsch mit fwrite im Binärformat funktioniert nicht
-
Hallo,
ich suche schon ewig nach einer Lösung meines Problems, eine Zeile einer 2-dimensionalen Matrix in einem Rutsch zu speichern. Hab auch schon in diversen Foren gesucht. Ich muss wohl einen Denkfehler haben, dass ich das Problem nicht allein lösen kann. So, nun erst mal der Code:
void CInGaAs_01Dlg::OnButton2() { int *m_imatrix[512], m_iintegral[512]; int i=0,j=0,dimy=10; for(i=0;i<512;i++) m_imatrix[i]=new int[dimy]; //512 x dimy-Matrix erzeugen for(j=0;j<dimy;j++) { for(i=0;i<512;i++) m_imatrix[i][j]=j+1; } CFileDialog m_ldFile(FALSE); FILE * pFile; if(m_ldFile.DoModal()==IDOK) { m_sFileName=m_ldFile.GetFileName(); //Für Anzeige neben Öffnen-Button m_sFileNameFull=m_ldFile.GetPathName(); UpdateData(FALSE); } pFile = fopen (m_sFileNameFull,"wt+"); if (pFile!=NULL) { for (i=0;i<=512-1;i++) { for(j=0;j<dimy;j++) { fprintf (pFile,"%d",m_imatrix[i][j]); //intensity if (j<dimy-1) fprintf (pFile," "); //field seperator } if (i<512-1) fprintf(pFile,"\n"); //record separator } fclose (pFile); MessageBox("Datei wurde erfolgreich gespeichert!","Fertig!",MB_OK); } struct CL_HEADERSTRU *cl=NULL; FILE *file_csi=NULL; short ix,iy; //Speicher fuer Header allocieren if (!cl) if(!(cl=(struct CL_HEADERSTRU *)calloc(1,sizeof(struct CL_HEADERSTRU)))) MessageBox("Cannot allocate Memory","Error", MB_OK); //Header setzen cl->mag=7235; cl->XSize=20,7; cl->YSize=5500; cl->Center=500; cl->Disp=300; cl->Line=300; cl->Flags=1; cl->ix=256; cl->iy=200; cl->type=0; cl->chan=512; cl->acc=15; cl->temp=5; cl->strom=10; cl->kl_spalt=200; cl->line_x1=101; cl->line_y1=102; cl->line_x2=103; cl->line_y2=104; ix=cl->ix; iy=cl->iy; if(m_ldFile.DoModal()==IDOK) { m_sFileName=m_ldFile.GetFileName(); //Für Anzeige neben Öffnen-Button m_sFileNameFull=m_ldFile.GetPathName(); UpdateData(FALSE); } //File oeffenen if ((file_csi = fopen(m_sFileNameFull,"w+b")) == NULL) //fopen(Filename,"w+b") { MessageBox("Cannot allocate Memory","Error", MB_OK); return; } //Integrales Spektrum berechnen for(i=0;i<512;i++) { m_iintegral[i]=0; for(j=0;j<dimy;j++) m_iintegral[i]+=m_imatrix[i][j]; } //Schreiben fwrite(cl,sizeof(struct CL_HEADERSTRU),1,file_csi); //for(j=0;j<dimy;j++) for(i=0;i<512;i++) fwrite((short int*)&m_imatrix[i][j],sizeof(short int),1,file_csi); for(j=0;j<dimy;j++) { fwrite((short int*)&m_imatrix[0][j],sizeof(short int*512,1,file_csi); } fwrite((short int*)&m_iintegral,sizeof(short int)*cl->chan,1,file_csi); fclose (file_csi); free(cl); MessageBox("CSI-Datei geschrieben","Error", MB_OK); }Was ich mache, ist ganz einfach. Ich lege mir einfach im oberen Teil eine 512x10-Matrix an und fülle die dann mit simplen Werten. Dann speichere ich einmal die Matrix in einer Text-Datei im Spaltenformat und abschließend im Binärformat(brauch ich für ein Auswerteprogramm).
struct CL_HEADERSTRU *cl=NULL;ist einfach nur eine Struktur die als Header der Datei abgespeichert wird. Das funktioniert alles. Wenn ich diese Zeile hier benutze:
//for(j=0;j<dimy;j++) for(i=0;i<512;i++) fwrite((short int*)&m_imatrix[i][j],sizeof(short int),1,file_csi);zum speichern der Matrix, dann klappt alles wunderbar und ich kann mit einem Hex-Editor das speichern nachvollziehen. Das läuft. Benutze ich aber:
for(j=0;j<dimy;j++) { fwrite((short int*)&m_imatrix[0][j],sizeof(short int)*512,1,file_csi); }zum Speichern einer kompletten Zeile (512 Werte), dann funktioniert zwar das Speichern an sich, aber ich bekomme für diesen Teil der Datei nur Datenmüll. Die letzte fwrite-Anweisung klappt wieder wunderbar.
Was mache ich nur falsch? Ich will doch nur nach und nach eine Zeile nach der anderen in einem Rutsch speichern. Ich bitte um Hilfe
-
sorry, wenn ich noch mal poste. eigentlicher autor ist torstenschw. registrierung war wohl noch nicht so schnell wie mein beitrag..
-
torstenschw schrieb:
sorry, wenn ich noch mal poste. eigentlicher autor ist torstenschw. registrierung war wohl noch nicht so schnell wie mein beitrag..
Du hast einen kleinen Denkfehler. Dein Array of pointer (int
enthält 512 Zeiger beim fwrite gehst Du dann aber irgendwann einmal von 512 integers aus. Du hast aber immer nur dimy (also 10) integers hintereinander im Speicher. Deshalb kann Dein fwrite nicht das gewünschte Ergebnis liefern.mfg Martin
-
wenn ich also bei mir die defintion meiner matrix von matrix[512][10] auf matrix[10][512] abändere, sollte es gehen oder?
-
torstenschw schrieb:
wenn ich also bei mir die defintion meiner matrix von matrix[512][10] auf matrix[10][512] abändere, sollte es gehen oder?
Momentmal Deine Matrix sieht doch so aus:
int *m_imatrix[512];Wenn Du Deine Matrix so definierst:
int matrix[512][10];oder so
int matrix[10][512];Dann kannst Du sie auch so speichern:
fwrite( matrix, sizeof(int)*512*10, 1, fp );mfg Martin
-
mgaeckler schrieb:
fwrite( matrix, sizeof(int)*512*10, 1, fp );hab eben mal deine code mit meiner alten matrix-defintion verwendet. leider kommt da im Hex-Editor immer noch Datenmüll an. Was ich brauche, ist, dass da jetzt laut Belegung der Matrix im Programm 512x hintereinander eine 1 steht, dann 512x eine 2 und sofort. Leider sehe ich das im Hex-Editor nicht.
Aber ich bin dir schon mal sehr dankbar, dass du dich auf meine Problemstellung einlässt.
-
aber so sollte es funktionieren, wie mgaeckler geschrieben hat - hast du mal mit dem debugger geguckt, ob in matrix auch das steht, was du gern hättest?
bb
PS: Dir ist bewusst, dass das C und kein C++ ist?
-
im debugger habe ich mir das auch schon angeguckt, da passt alles mit der matrix (an mehreren stellen geprüft). nur leider schreibt er müll in die datei. wie sieht denn bei euch die binärdatei aus? würde das gerne mal sehen.
zu c/c++: ja, ich hab auch etwas c drin, aber ging nicht anders.
-
hm - also so funktioniert es jedenfalls:
#include <cassert> #include <cstdio> int main() { int matrix[10][512] = {}; matrix[3][12] = 1; FILE *c_gefrickel = fopen("asd", "w"); fwrite(matrix, sizeof(int), 10*512, c_gefrickel); fclose(c_gefrickel); c_gefrickel = fopen("asd", "r"); fread(matrix, sizeof(int), 10*512, c_gefrickel); fclose(c_gefrickel); assert(matrix[3][12] == 1); }bb
-
dank dir unskilled. jetzt fabriziere ich zumindest keinen datenmüll mehr.
hab meine matrix jetzt wie bei dir definiert überint m_imatrix[10][512];das ganze wieder mit zahlen gefüllt und über
fwrite((short int*)m_imatrix,sizeof(short int)*512*10,1,file_csi);leider hab ich immer noch ein kleines problem: jetzt speichert er nur die hälfte der daten ab. hab da anscheinend noch probleme mit dem casten. im hex-editor siehts dann so aus, 01 00 00 00 01 00 00 00 01 ....
also immer 2Byte zuviel mit einer Null belegt, was ich nicht ganz versteh, da meine ausgerechnete dateigröße mit der erzeugten übereinstimmt.
-
guck dir doch mal an, wie ich die fkt aufgerufen habe und wie du sie aufrufst...
das hat schon nen sinn, dass die elementgröße und elementanzahl getrennt übergeben werden und nicht einfach miteinander multipliziert werden.
(wenn du mal guckst, wirst du nur die hälfte abgespeichert haben)aber vermutlich wird dann die falsche hälfte der zahl gespeichert : D
wieso willst du unbedingt nur shorts speichern?bb
-
ok, das mit der elementgröße und anzahl sehe ich ein (klappt trotzdem nicht). short int brauche ich dann für ein anderes programm, mit die daten dann eingelesen werden. das braucht halt short int. das auswerteprogramm wird auch nicht mehr geändert.
-
und was heißt klappt trotzdem nciht? ich merk aber gerade selbst, dass es nicht klappen kann

naja - short int ist zwar doof(in jeder beziehung, weil 0 vorteile, außer nur halb so große datei, aber das sollte eh egal sein), aber wenns denn sein muss, wirst du nicht umherkommen, das int-array in nen short-array umzukopieren.
z.B. so:
int matrix[10][512]; short schreib_mich[10*512]; for(std::size_t i(0); i != 10*512; ++i) { schreib_mich[i] = matrix[i/512][i%512]; } FILE* fd = fopen("asd", "w"); fwrite(schreib_mich, sizeof(short), 10*512, fd); fclose(fd);bb
-
danke noch mal für deine mühen. ich hab leider gerade keine zeit mehr, um deinen code zu testen. morgen setz ich mich noch mal dran. aber meinst nicht, dass der anfang der for-schleife so lauten sollte;
for(i=0;i!=10*512;i++)was dann kommt, versteh ich leider nicht so ganz. da sind meine c/c++-kenntnisse zu schlecht, aber ich will mich reinfuchsen. % = modulo?
grüße
-
nein, die for-schleife ist so richtig, wie sie ist.
du kannst im initialisierungsteil auch neue variablen anlegen:
for(int i=0; i != 12; ++i)
kennst du ja sicherlich, genau so geht es auch, andere typen als int zu nehmen.
und stattint i=0kann man auchint i(0)schreiben.% heißt modulo, japp (also welcher rest bei der division entsteht)
ich habs so doof geschrieben, weil ich zu faul für die 2. schleife war, macht genau das gleiche wie:for(int i=0; i != 10; ++i) { for(int j=0; j != 512; ++j) { /*mache irgendwas mit*/ matrix[i][j]; } }bb
-
so, jetzt klappt alles. wunderbar
