Fehler in Code table[i]-Problem?
-
Hallo,
ich habe lange nicht mit C oder C++ gearbeitet. Die table-Funktion habe ich noch nie benutzt. Den Programmcode habe ich versucht anhand eines bestehenden Codes aufzubauen. Ziel ist 2 Dateien mit je einer Lise an Werten einzulesen, zu vergleichen und jeweils die Zeilen mit Luft ("1 0.0012 0") in Phantom1 zu ersetzen durch den Wert in Phantom2.
(Theoretisch ginge das sehr einfach mit Excel, aber da meine Dateien über 125 Mio Zeilen haben, muss ich das auf diesem Weg machen)Die Textdateien sind folgendermaßen aufgebaut (einfachere kleine Testversionen):
Phantom1# >>>> MC-GPU / penEasy 2008 VOXEL GEOMETRY FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Geometry imported from the Zubal phantom (file: 'voxel_man.dat.vox') # See info in: http://noodle.med.yale.edu/zubal/ # [SECTION VOXELS HEADER v.2008-04-13] 2 3 2 No. OF VOXELS IN X,Y,Z 2 2 2 VOXEL SIZE (cm) ALONG X,Y,Z 1 COLUMN NUMBER WHERE MATERIAL ID IS LOCATED 2 COLUMN NUMBER WHERE THE MASS DENSITY IS LOCATED 1 BLANK LINES AT END OF X,Y-CYCLES (1=YES,0=NO) [END OF VXH SECTION] 1 0.5 0 5 1.0012 0 3 2.0012 0 1 0.0012 0 1 1.2000 0 1 0.0012 0 1 0.5 0 5 1.0012 0 3 2.0012 0 1 0.0012 0 1 1.2000 0 1 0.0012 0 # >>>> END OF VOXEL FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Phantom2
# >>>> MC-GPU / penEasy 2008 VOXEL GEOMETRY FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Geometry imported from the Zubal phantom (file: 'voxel_man.dat.vox') # See info in: http://noodle.med.yale.edu/zubal/ # [SECTION VOXELS HEADER v.2008-04-13] 2 3 2 No. OF VOXELS IN X,Y,Z 2 2 2 VOXEL SIZE (cm) ALONG X,Y,Z 1 COLUMN NUMBER WHERE MATERIAL ID IS LOCATED 2 COLUMN NUMBER WHERE THE MASS DENSITY IS LOCATED 1 BLANK LINES AT END OF X,Y-CYCLES (1=YES,0=NO) [END OF VXH SECTION] 1 0.0012 0 1 0.0012 0 1 0.0012 0 5 2.0012 0 1 1.2000 0 1 0.0012 0 1 0.0012 0 5 1.0012 0 1 0.0012 0 5 2.0012 0 1 1.2000 0 1 0.0012 0 # >>>> END OF VOXEL FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Programmcode:
#include <stdio.h> #include <string.h> #include <stdlib.h> // Structure with the info for each voxel number read from the phantom description file (ie, values that will be found in the raw data): struct merging_table { int mc_material1; int mc_material2; int density1; int density2; int id1; int id2; }; int main(int argc, char * argv[]) { printf("\n ** Merging 2 files **\n"); // if (argc != 3) // { // printf(" Usage: ./merge.x Phantom1.vox Phantom2.vox\n"); // printf(" (Output will be written to file: phantommerged.vox)\n\n"); // exit(0); // } int id1, id2, mc_material1, mc_material2, i; float density1, density2; char new_line[250], organ_name[30], *dummy; char*str = realloc(NULL,100); struct merging_table table[150]; FILE* file_phantom1 = fopen(argv[1], "r"); // -- Read Phantom 1: for(i=0; i<33; i++) { if (strstr(new_line,"# >>>> END OF VOXEL FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") != NULL) { break; // We arrived at the end of the conversion table } else { sscanf(new_line, "%d %f %d ",&mc_material1, &density1, &id1); table[i].mc_material1 = mc_material1; table[i].density1 = density1; table[i].id1 = id1; printf("%d %.3f %d\n", table[i].mc_material1, table[i].density1, table[i].id1); } } FILE* file_phantom2 = fopen(argv[1], "r"); // -- Read Phantom 2: for(i=0; i<33; i++) { if (strstr(new_line,"# >>>> END OF VOXEL FILE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") != NULL) { break; // We arrived at the end of the conversion table } else { sscanf(new_line, "%d %f %d ",&mc_material2, &density2, &id2); table[i].mc_material2 = mc_material2; table[i].density2 = density2; table[i].id2 = id2; } } fclose(file_phantom2); // Close the file after finding the relevant data (it will be re-opened next iteration of the loop) // -- Open the raw data file and create the output file (with '.vox' appended): FILE* file_output = fopen(strcat(argv[2],"merge.vox"), "w"); // -- Write the output file in the order expected for penEasy (x++,y+,z), with blanks between rows and double blanks between planes. Three columns are written: 1) mc_material, 2) density, 3) organ_number (optional column, may help when defining more materials or computing organ doses). for(i=11; i<32; i++) { if (table[i].mc_material1 ==1 && table[i].density1 ==0.0012 && table[i].id1 == 0) // Write material of phantom2 if material of phantom1 is air fprintf(file_output, "%d %.3f %d\n", table[i].mc_material2, table[i].density2, table[i].id2); else // Write material of phantom1 if material of phantom1 is NOT air fprintf(file_output, "%d %.3f %d\n", table[i].mc_material1, table[i].density1, table[i].id1); } fclose(file_phantom1); fclose(file_phantom2); printf("\n\a ==> Conversion happily finished! :-) <== \a \n\n"); realloc(str,0); return 0; }
Die printf ausgabe in Zeile 57 ist grad nur zum testen drin.
printf("%d %.3f %d\n", table[i].mc_material1, table[i].density1, table[i].id1);
Wenn ich testweise in Zeile 54-56 mc_material1, density1 und id1 durch die Ziffern 1, 2 und 3 ersetze, läuft das programm (gespeichert wird aber trotzdem keine Datei) und es wird "1 0.000 3" ausgegeben. mit dem richtigen Programmcode wie er oben steht, stürzt das Programm ab und es wird nur "0 0.000 -1" ausgegeben.
Wahrscheinlich ist das nur ein simpler Fehler, den ihr direkt aufklären könnt. Ich werd mich später noch mal darüber belesen, aber sitz schon den ganzen Tag dran und langsam nervts
lg
-
Zeile 40 und 61:
Du willst zweimal dieselbe Datei öffnen. Allerdings hast du vor dem zweiten öffnen, die Datei nicht geschlossen.Der Speicher von argv gehört dir nicht, ausserdem weißt du auch nicht, wieviel Platz darin frei ist. Darum darfst du ihn nicht beschreiben.
Dein strcat(argv[... ist also falsch.Es iteressiert dich auch nicht, ob die Zeilen sinnvolle Daten enthalten.
Du versuchst einfach zu lesen und interessierst dich nicht für den Erfolg der Aktion (Rückgabewert vonscanf
)Du machst zweimal fclose(file_phantom2);
Deine Datenstruktur ist auch nicht so toll.
Mach eine struct für einen Datensatz.
Den kannst du dann in ein Array oder wieder einestruct
packen.Willst du wirklich alle Daten erst einlesen und dann mergen?
Wie wäre es zeilenweise? Dann brauchst du immer nur Speicher für eben diese Zeile.
-
serenity99 schrieb:
Wahrscheinlich ist das nur ein simpler Fehler, den ihr direkt aufklären könnt.
Da brauchen wir nicht einmal ran, viele Fehler findet bereits dein Compiler, du hörst bloß nicht auf ihn:
test.c:56:7: warning: format '%f' expects argument of type 'double', but argument 3 has type 'int' [-Wformat=] printf("%d %.3f %d\n", table[i].mc_material1, table[i].density1, table[i].id1); ^ test.c:97:12: warning: format '%f' expects argument of type 'double', but argument 4 has type 'int' [-Wformat=] fprintf(file_output, "%d %.3f %d\n", table[i].mc_material2, table[i].density2, table[i].id2); ^ test.c:100:11: warning: format '%f' expects argument of type 'double', but argument 4 has type 'int' [-Wformat=] fprintf(file_output, "%d %.3f %d\n", table[i].mc_material1, table[i].density1, table[i].id1); ^ test.c:32:40: warning: unused variable 'dummy' [-Wunused-variable] char new_line[250], organ_name[30], *dummy; ^ test.c:32:23: warning: unused variable 'organ_name' [-Wunused-variable] char new_line[250], organ_name[30], *dummy; ^ test.c:17:14: warning: unused parameter 'argc' [-Wunused-parameter] int main(int argc, char * argv[]) ^ test.c:109:10: warning: ignoring return value of 'realloc', declared with attribute warn_unused_result [-Wunused-result] realloc(str,0);
Mach das erst einmal alles richtig, dann gucken wir weiter.
-
mein compiler (dev c++) hat gar keine Fehler ausgegeben.
Zudem habe ich bereits gesagt, dass ich einen bestehenden code (von einer anderen person) als Grundlage verwendet habe. Kein Grund also einen so unfreundlichen Ton anzuschlagen.
-
serenity99 schrieb:
mein compiler (dev c++) hat gar keine Fehler ausgegeben.
Dev C++ ist kein Compiler, sondern eine (veraltete) IDE. Da diese intern den GCC-Compiler benutzt (solange du nichts anderes einstellst) wäre dieser absolut in der Lage, diese Warnungen auszugeben, denn obige Warnungen habe ich erzeugt, indem ich deinen Code mit eben diesem Compiler übersetzt habe. Aber eben mit eingeschalteten Warnungen. Du solltest immer alle Warnungen einschalten und Warnungen wie Fehler behandeln. Der Compiler hat damit fast immer Recht. Die Regeln der Sprache C sind bloß so tolerant, dass vieles, was offensichtlich falsch ist, nicht als echter Fehler zählt, für den Fall, dass der Programmierer sich dabei etwas Superschlaues gedacht hat.
Zudem habe ich bereits gesagt, dass ich einen bestehenden code (von einer anderen person) als Grundlage verwendet habe.
Ist das ein Grund, Fehler nicht zu verbessern?
Kein Grund also einen so unfreundlichen Ton anzuschlagen.
Verwechsele Direktheit nicht mit Grobheit. Bloß weil ich, oder jemand anderes, Beiträge nicht mit rosa Blümchen verziert, ist das nicht unfreundlich gemeint. Der Ton in Programmierforen ist sachlich und direkt. Mein Beitrag sollte folgendes aussagen:
-Was (einige der) Fehler sind.
-Dass du die genannten Fehler auch sehr einfach selber hättest finden können (als Aufforderung zu verstehen, dies beim nächsten Mal zuerst zu versuchen).
-Wie du die Fehler auch hättest sehr leicht selber finden können.
-Dass du die Fehler verbessern solltest.
Wenn dir irgendwas da dran nicht passt, dann ist dir schwerlich zu helfen.