Datensatz-Datei auslesen



  • Hallo,

    bin nun schon viel weiter und dafür schon mal vielen Dank für eure Hilfe!

    Wieder ne kleine Randfrage:

    Ich habe 9 Dateien die fast gleich heißen bspw. BLA_X.dat. Das X ist eine Variable die sich ändert. Ich möchte diese nun nach einander einlesen. Dafür ist natürlich eine Zählschleife ausgezeichnet. Dazu muss ich ja den fopen-Pfad irgendwie variabel machen. Ist sowas möglich?



  • Schau dir mal sprintf an: http://www.cplusplus.com/reference/cstdio/sprintf/

    int X = 0;
       char dateiname[260];  // Für die 260 gibt es in irgendeinem Header auch eine Konstate/Makro
    ...
       sprintf(dateiname, "BLA_%d.dat", X);
       datei_mess=fopen(dateiname, "r");
    


  • Super Danke dir!



  • Das sowieso überall die 9 auftaucht, kannst du für das in auch
    FILE *in[9]; nehmen. Dann aber ohne calloc .

    Dann klappt es auch mit fopen und fread.

    Da das FileOpen ein int als Handle zurück gibt, bin ich mir nicht sicher, ob das überhaupt etwas mit C++ zu tun hat.



  • "Er" verwendet wahrscheinlich int-Handles für den Dateizugriff, in reinem C gibts aber nur FILE* dafür (in POSIX kann man FILE* auf int wandeln und statt fopen/fread/fwrite dann open/read/write benutzen), könnte z.B. dann so aussehen:

    unsigned char   werte[24];
    FILE            *in[9];
    
    ...
    //setzen auf die Dateinamnen
    for(i=0;i<9;i++)
    {
      in[i]=fopen(dateiname,"rb"); /* binär ist wichtig */
    }
    
    ...
    
    //Code fürs einlesen
     for(j=0;j<9;j++)
      {
      for(k=0;k<6;k++)
      {
    
        if( 1 == fread(werte,24,1,in[j]) )
    


  • Es ist etwas kompliziert, da er nachdem er die Dateien gelesen hat, noch etwas Daten verschieben muss, damit er die Werte korrekt im Rechner hat. Leider habe ich dazu (noch) keinen Code gefunden.
    Er erstellt mir zwar eine Datei und schreibt auch Werte rein, die stimmen sollten, aber leider nicht genug. Wenn man sich die Datei anschaut, dann sieht es so aus, als ob dort nur die Werte von einer Quell-Datei gelesen und anschließend geschrieben werden.



  • Guten Morgen zusammen,

    ich habe mir die Datei angeschaut, welche erstellt wird und da sind deutlich zu wenig Daten drin. Am Anfang sieht alles gut aus, aber dann folgen nur noch "0" bis zum Ende.
    Irgendwas scheint da ja nicht zu stimmen.

    Denke mal mit dem Befehl fread() klappt etwas nicht genau.

    fread(dd, 24, 1, datei_in[j]);
    

    1. Ziel
    2. Blockgröße
    3. Anzahl der Blöcke
    4. Quell-Datei

    Ich muss in Blöcken von 24 Byte auslesen, aber mit dem oberen Aufruf würde ich ja nur einem Block von 24 Byte lesen und das kann nicht stimmen.

    Eine Datei von der Scannereinheit ist übrigens 72 000 018 Byte groß



  • Pinockel schrieb:

    Ich muss in Blöcken von 24 Byte auslesen, aber mit dem oberen Aufruf würde ich ja nur einem Block von 24 Byte lesen und das kann nicht stimmen.

    Dann musst du halt mehrmals lesen.

    Pinockel schrieb:

    Eine Datei von der Scannereinheit ist übrigens 72 000 018 Byte groß

    Oder knapp 69 MB Speicher anfordern und einmal lesen.



  • Guten Morgen,

    konnte das Problem lösen, war ein kleiner Denkfehler von mir drin 🙂

    Nun habe ich aber einen rechnerisches. Er erstellt die Dateien und auch sichtbar ist das Bild, aber wenn ich mir die Referenz-Datei und die selbst erstellte Datei ansehe (Okteta), dann habe ich immer leicht andere Werte in der selbst erstellen Datei drin stehen. Somit sieht das Bild nicht exakt aus wie auf dem Referenzbild.

    Da die Berechnungen gleich sind, kann es eigentlich nur an der Deklaration, Eingabe oder Ausgabe liegen. Hier mal die beiden Deklarationen bzw. ein Datentyp-Problem
    Größe der beiden Dateien ist auf jeden Fall gleich und das sollte schon mal gut sein.

    Meine in C

    FILE *datei_mess, *datei_in[9];
    int nfiles = 9, zuord[9], k, j, i, NSamp;
    double dif;
    unsigned char dd[24], dateiname[255];
    unsigned short *data, *data2;
    

    Original in C++

    int             i,j,k,nfiles,NSamp,fid_out /*<-Ausgabe-Strom*/;
    unsigned char   dd[24]//Hier wird Eingabe gespeichert;
    int             *fid_in /*<-Lese-Strom*/,zuord[9];
    unsigned short  *data,*data2; //beides Rechen-Array
    

    Bin für jeden Tipp sehr dankbar 😉

    LG



  • Woher weißt du, dass die Berechnungen gleich sind?

    Gerade da gibt es genug Fallstricke die man umgehen muss.

    Die Berechnunmgen laufen unter C nicht immer so wie man das mathematisch gewohnt ist.
    Z.B die Integerdivision, kleinster Datentyp bei der Berechnung ist int bzw. double.



  • Ach so, weil ich den Code für die Berechnung kopiert habe, deswegen dachte ich, kann ich die Berechnung als Fehlerquelle ausschließen



  • Du hast ja nicht geschrieben, wie du ihn kopiert hast.

    Der einzige Unterschied bei den Definitionen sollte dann auch bei den Filedeskriptoren sein.

    Ohne Code wird dir da keiner weiterhelfen können.



  • Es ist im Prinzip eine Bit-Schieberei um die Werte richtig einzulesen:

    fread(dd, 24, 1, datei_in[j]);
    data[j * 96 + k * 16 + 7 - 0] = dd[1] * 16 + (dd[0] & 0xF0) / 16;
    data[j * 96 + k * 16 + 7 - 1] = (dd[0] & 0x0F) * 256 + dd[3];
    ...
    //Geht paar mal so weiter
    ...
    

    j,k sind die Schleifenzähler. Hoffe das hilft etwas weiter bzw. gibt ein Einblick wo der Problem liegen könnte.



  • Ok, nochmal:

    Ohne Code² wird dir da keiner weiterhelfen können.

    ²Minimal und vollständig. Mit den benötigten Variablen, Berechnungen und Dateioperationen (open,close,read,write)
    In deinem Fall auch den C++ Code, denn du suchst ja den Unterschied.



  • Das Problem hat sich erledigt, da es doch nicht mehr gebraucht wird.

    Ich habe nun aber eine weitere kleine Frage.

    Main initialisiert ein Array und dieses soll etwas in einer weiteren Funktion bearbeitet werden. Irgendwie klappt jedoch die Berechnung nicht ganz. Beim Debuggen habe ich exorbitante Werte.

    Hier der CODE

    double Berechnung(double *Array, double x, double y) 
    {
    double temp;
    temp = Array[(int)x + (int)y];
    return temp;
    

    Danke schon mal und ich hoffe der Code hilft diesmal weiter 😉 Sorry nochmal.

    Ihr seht nix großes aber irgendwie klappt die Übergabe nicht. Ich möchte das der Rückgabewert ist, der im X+Y-ten Array drinsteht.

    Gespeichert werden wollte ich so realisieren:

    int i;
    double Array[500*432];
    double Array_neu[500*432];
    
    for (i=0; i<10; i++)
    {
    Array_neu[i] = Berechnung(&Array[0], i+1.0, i+2.0);
    ]
    


  • Pinockel schrieb:

    Hier der CODE
    ...
    Danke schon mal und ich hoffe der Code hilft diesmal weiter 😉

    Nein, tut er nicht.

    Wie initialsierst du den Speicher?
    Woher weisst du, das die Werte falsch sind?
    Warum sind x und y als double definiert (und nicht als int oder size_t )?

    Meinst du evtl. Array[y*432+x] oder Array[y*500+x] ? (Der Zahlenwert steht für die Anzahl der Spalten)



  • In einer Datei liegen 432*500 double Werte. Das entspricht dem 1. Bild. Nun muss dieses etwas umgewandelt werden.
    Ich wollte die Werte, direkt hintereinander einlesen, also ohne 2D Array, weil ich eine Funktion gestellt bekomme, welche aber nur mit einem 1D Array arbeiten kann.

    Speicher stelle ich so bereit:

    double Array[500*432], SinFan_neu[500*256];
    

    Kein Schreibfehler! Das zweite Array ist bewusst kleiner.

    So lese ich die Datei:

    FILE *datei, *datei_neu;
    fread(Array, sizeof(Array), 1, datei);
    

    So rufe ich die Funktion auf:

    for (p = 0; p < 500; p++) {
    for (s = 0; s < 256; s++) {
    SinPara_data[s + p * 256 = Berechnung(&Array[0], 432, 500);
    

    So schreibe ich die Datei:

    fwrite(Array_neu, sizeof(Array_neu), 1, datei_neu);
    

    Falls noch was gebraucht wird. Reiche ich das gern nach.



  • Dein 2. Array ist zu klein um alle Elemente deines 1. Arrays aufzunehmen.
    Du schreibst Müll in deinen Speicher hinter dem 2. Array. Deine Zeile des 2. Array ist kleiner als die des 1. Arrays, d.h. du schreibst Werte aus Zeile 1 des 1. Arrays in Zeile 2 des 2. Arrays. Das kann nur falsch sein.
    Deine Index-Berechnung ist auch laienhaft und fehleranfällig, besser wäre z.B.

    double (*z)[256] = SinPara_data;
    for (p = 0; p < 500; p++) {
    for (s = 0; s < 256; s++) {
    z[p][s] = Berechnung(Array, 432, 500);
    


  • Danke für deine Antwort. Hab den Code oben geändert, da ist einiges schief gelaufen!

    Meine innere Zählschleife geht auch nur solange s<256 den Fehler hatte ich auch schon entdeckt und korrigiert.

    Und das Array sollte doch von der Größe her reichen, wenn die innere Schleife nur <256 läuft. Gibt als maximalen Index.

    Array [ 256499 + 255] = 127 999
    Mein Array ist [500
    256] = 128 000 groß


Anmelden zum Antworten