machen Compiler Unterschiede zwischen 32bit und 64bit-Systemen?



  • Hallo Leute,

    ich habe ein Problem beim Kompilieren eines Programms, welches ich nicht selber geschrieben habe (ich habe nur sehr geringe Ahnung von c++).
    Das recht kleine Programm nutzt zwei .cpp und eine .h Datei, die jeweils in c++ geschrieben sind. Wenn ich das Programm kompiliere nutze ich folgenden Befehl:

    g++ -o Programmname datei1.cpp datei2.cpp
    

    Wenn ich das auf einem SuSE 9.2 System mache, läuft das Programm und macht, was es soll.
    Wenn ich aber das Ganze auf einem SuSE 10.1 64-bit System mache, startet das Programm ganz normal, aber es macht nicht wirklich, was es soll.

    Hintergrund zum Programm:
    Das Programm liest eine ascii-Datei aus, in der Messdaten gespeichert sind, ca. 16000 Datenblöcke, die durch jeweils zwei Leerzeilen getrennt sind, und ca. 2000 Zeilen mit 4 Spalten enthalten. Diese Daten werden einfach binär in eine neue Datei geschrieben.

    Das nicht korrekt arbeitende Programm auf dem 64bit-System, macht daraus aber leider 8 Datenblöcke mit ca. 4.3 Millionen Zeilen. Das ist ja nicht wirklich das Gleiche wie vorher!

    Kann es also sein, dass da der compiler irgendetwas vergriesgnaddelt?

    Wenn ich das auf SuSE 9.2 (32-bit) kompilierte Programm auf dem 64-bit System laufen lasse, macht es aus den Daten irgendwie einen Datenblock mit 6.5 Millionen Zeilen. Also geht da dann auch einiges schief.

    Wenn ich das auf dem 64-bit System kompilierte Programm auf dem 32-bit System laufen lasse, bekomme ich folgende Fehlermeldung:

    -bash: ./dat2pqx2: cannot execute binary file
    

    dat2pqx2 heisst das Programm.
    Hat dazu vielleicht jemand ne Idee?
    Kann das echt an den Unterschiedlichen Systemen liegen?

    Ich hoffe Ihr könnt mir helfen!



  • Natürlich macht der Compiler da Unterschied, was glaubst du, warum die 64-Bit-Architektur anders heißt?! Wenn du mal file mit diesen Binärdateien aufrufst wirst du das auch sehen, dass sagt dir nämlich sowas wie "ELF 32 Bit Binary" oder "ELF 64 Bit Binary", je nach dem, auf welcher Architektur du es kompiliert hast.
    Der Hauptunterschied ist afaik, das normale Zeiger 64-Bit lang sind. Beim gcc ist auch long 64-Bit, im Gegensatz zu 32-Bit-Plattform. Idealerweise versuchst du, die Probleme in diesem Bereich zu suchen, ansonsten kannst du das Programm auf der 64-Bit-Maschine mit der Compiler-Flag -m32 probieren, die kompiliert für 32-Bit (was aber nur funktioniert, wenn das Programm keine Abhängigkeiten hat, die nur als 64-Bit-Version verfügbar sind.



  • Super, Danke für die Antwort. Ich werde dem gleich mal nachgehen.
    Das Programm wurde auf nem 32-bit System geschrieben und hat auch bisher nur auf einem solchen System gearbeitet. Somit sollte es keine 64-bit Abhängigkeiten haben. Mich wundert, dass es in dem Programm einen Unterschied macht, ob ein Zeiger 32-bit oder 64-bit lang ist, wenn denn das das Problem sein soll. Naja, ich versuche es mal mit dem -m32 flag.

    Danke nochmals.



  • Hmm, klappt nicht.

    Ich bekomme beim Kompilieren folgende Fehlermeldung:

    In file included from /usr/include/features.h:346,
                     from /usr/include/time.h:29,
                     from dat2pqx.cpp:2:
    /usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: Datei oder Verzeichnis nicht gefunden
    

    Habe dann die glibc-devel-32bit nachinstalliert => keine Fehlermeldung mehr.

    Das Programm macht nun nur noch 488 Datenblöcke mit 65000 Zeilen. Also auch noch nicht ganz korrekt.

    Gibt es noch weitere -m-flags, die ich nutzen sollte?

    Ich habe mir "man gcc" mal angesehen, aber bis ich da durchgestiegen bin ist wohl Weihnachten vorbei, also 2008.

    Wenn es an den Definitionen der 'long, double, int, float, usw' liegen sollte, muss ich die alle einzeln mit -mlong32 -mfloat32 usw. umsetzen?
    [EDIT] ok, offensichtlich sind diese Optionen garnicht für nen Athlon 64-bit System verfügbar.



  • Kannst du eventuell den betreffenden Teil (einlesen der Daten) finden und posten? Das Programm auf 32-Bit zu kompilieren kann eigentlich keine Lösung sein...



  • Also ich glaube so ganz lang ist der Code ja nicht, den kann ich ja mal hier reinkopieren.

    int main(int argc, char* argv[])
    {
            // Zeiger auf ein PQXFile-Objekt anlegen
            PQXFile *pqx = new PQXFile();
    
            // Datenstrukturen anlegen
            PQXFileHeader   pfh;
            PQXBlockHeader  pbh;
            PQXData        *data;
    
            // andere Variable
            FILE *f;
            char buffer[100];
            int i;
            float f1,f2,f3,f4;
    
            // PQXFileHeader fuellen - Werte aus Header in .dat!
            std::string datei;
            int sf, enter;
            int ppb;
    
           char cfindText[8];
           int m;
           FILE *File;
    
            cout << "Dateiname: ";
            getline(cin, datei);
    
          // Daten aus Header lesen
    
          File = fopen(datei.c_str(), "r");
    
          for(m = 0; m < 10; m++)
              {
              cfindText[m] = fgetc(File);
              }
          while(!feof(File))
              {
    
              if(!strcmp(cfindText, "of Points: "))
              {
              fscanf(File, "%i", &ppb);
              cout << "Points per spectrum: " << ppb <<"\n";
              }
              if(!strcmp(cfindText, "Frequency:"))
                   {
                   fscanf(File, "%i", &sf);
                   cout << "Frequency: " << sf <<"\n";
                   }
               for(m = 0; m < 9; m++)
                   {
                   cfindText[m] = cfindText[m+1];
                   }                                      
            cfindText[9] = fgetc(File);
             }
         fclose(File);
    
            //cout << "Frequenz: ";
            // cin >> sf;
            //cout << "Punkte pro Spektrum: ";
            //cin >> ppb;
    
            pfh.SampleFrequency = sf;
            pfh.PointsPerBlock = ppb;
            pfh.StartTime       = 0; // keine Zeitinfo mehr...
    
            // Neue pqx-Datei zum Schreiben oeffnen
            pqx->WriteFile((datei+".pqx").c_str(), &pfh);
            //pqx->WriteFile(const_cast<char*>((datei+".pqx").c_str()), &pfh);
    
            // dat-Datei zum Lesen oeffnen
            f = fopen(datei.c_str(), "rt");
    
            // Speicher belegen
            data = new PQXData[pfh.PointsPerBlock];
    
            // PQXBlockHeader fuellen - alles auf Null
            pbh.TimeStamp = 0;
            for (i = 0; i < 8; i++)
            {
                    pbh.Counter[i] = 0;
                    pbh.DigitalIN[i] = 0;
            }
    
            // Lesen: Zunaechst Header ignorieren
            do {
                    fgets(buffer, 100, f);
                    printf(buffer);
            } while (buffer[0] == '#');
    
            // Jetzt Datenpunkte lesen
            while (!feof(f))
            {
                  for (i = 0; i < pfh.PointsPerBlock; i++)
                  {
                          sscanf(buffer, "%f %f %f %f\n", &f1, &f2, &f3, &f4);
    
                          // Umrechnung V - A/D-Werte
                          data[i].Ch[0] = f1 * 3276.8;
                          data[i].Ch[1] = f2 * 3276.8;
                          data[i].Ch[2] = f3 * 3276.8;
                          data[i].Ch[3] = f4 * 3276.8;
    
                          // Naechste Zeile holen
                          fgets(buffer, 100, f);
                  }
    
                  // Zweite Leerzeilen Xberlesen
                  fgets(buffer, 100, f);                                   
    
                  // Erste neue Zeile mit Daten holen fuer naechsten Durchlauf
                  fgets(buffer, 100, f);
    
                  // Daten in pqx-Datei schreiben
                  pqx->WriteBlock(&pbh, data);
            }
    
            // alles wieder schliessen
            fclose(f);
            delete data;
    
            return 0;
    }
    

    Ich hoffe da kannst Du was mit anfangen, ohne die andere .cpp und .h -Datei. Diese andere beiden Dateien bilden eigentlich die Grundlage für weitere Programme, die daraus kompiliert werden.



  • fgets(buffer, 100, f);
                    printf(buffer);
    

    gruselig. warum auch streams verwenden, wenn wir uns mit C viel schneller den fuß wegschießen können... 😉

    hier ist nicht viel zu erkennen. die implmentation dieser PQX... typen spielt möglicherweise auch eine rolle. jedenfalls finden dort offenbar auch I/O-operationen statt.

    edit: ich hab nichts gegen C I/O, wenn es angebracht ist - aber dann bitte richtig.



  • Nunja, ähm, wie oben schon bemerkt ist das Programm nicht von mir und da ich nicht viel c++ oder auch c verstehe, kann ich dazu jetzt leider mal rein garnichts sagen. Würde ich ja gerne richtig machen, aber dazu fehlt mir ein wenig knowhow. Sorry.

    Also, die PQXFiles sind in der header-Datei klassifiziert:

    typedef struct
    {
        char             ID[6];               // enthXlt "PQX11\0"
        double           SampleFrequency;     // Abtastrate
        unsigned long    PointsPerBlock;      // Anzahl Punkte je Block (= 2 Spektren)
        time_t           StartTime;           // Startzeit (in Sekunden seit dem 1.1.1970)
    //    char             Reserved[2026];      // macht 2048 Bytes gesamt
    } PQXFileHeader;
    
    #define PQXFileHeaderSize (sizeof(char)*6+sizeof(double)+sizeof(unsigned long)+sizeof(time_t))
    
    // PQX Daten
    typedef struct
    {
        signed short Ch[4];          // Kanaele 0-3
    } PQXData;
    
    #define PQXDataSize (4*sizeof(signed short))
    
    // PQX Block-Head
    typedef struct
    {
        clock_t       TimeStamp;           // Zeit seit erstem Spektrum in ms
        unsigned long Counter[8];          // Werte der Counter
        char          DigitalIN[8];        // Werte der DigitaleingXnge
    //    char          Reserved[980];       // macht 1024 Bytes gesamt
    } PQXBlockHeader;
    
    #define PQXBlockHeaderSize (sizeof(clock_t)+8*sizeof(unsigned long)+8*sizeof(char))
    
    class PQXFile
    {
    private:
        PQXFileHeader  pfh;
        PQXBlockHeader pbh;
        FILE          *f;                // Stream-Handle
        char     filename[1000];   // Dateiname
        long           Pos;              // Aktuelle Datei-Position, nur bei Lesezugriff
        long           Length;           // Dateigroessee, nur bei Lesezugriff
        bool           Write;            // Zugriffsmodus
    
    public:
    
        PQXFile(void);  // nur Initialisierung
        ~PQXFile(void); // schliesst Datei
    
        // Schreibzugriffe
        void WriteFile(const char *a_filename, PQXFileHeader *a_pfh); // zum Schreiben oeffnen
        void WriteBlock(PQXBlockHeader *a_pbh, PQXData *data);  // Datenblock schreiben
    
        // Lesezugriffe
        void    OpenFile(char *a_filename);  // zum Lesen oeffnen
        long    GetFileSize(void);           // Dateigroesse in Bytes
        long    GetNoOfBlocks(void);         // Anzahl der Blocks
        double  GetSampleFrequency(void);    // Daten aus File-Header
        long    GetPointsPerBlock(void);
        time_t  GetStartTime(void);
        char   *GetStartTimeString(void);      
    
        long    GetBlockNo(void);          // Nr. des aktuellen Blocks
        void    GotoBlock(long BlockNo);   // Zu Block gehen & Block-Header lesen
        void    ReadData(PQXData *data);   // Daten lesen
        void    ReadDataAndStepForward(PQXData *data);
                                         // Daten lesen & GotoBlock(GetBlockNo()+1)
        clock_t GetTimeStamp(void);        // Daten aus Block-Header
        double  GetTimeStampSeconds(void);
        long    GetCounter(int No);
        char    GetDigitalIN(int No);
    
        // Allgemeines
        char   *GetFileName(void);           // Pointer auf Dateinamen
    
        static long EstimateFileSize(long PointsPerBlock, long NoOfBlocks);
                                            // schaetzt Dateigroessee
    };
    
    #endif
    

    ... und verschiedene Funktionen werden in der zweiten .cpp-Datei deklariert:

    // nur ein paar Sachen initialisieren
    PQXFile::PQXFile(void)
    {
        f           = NULL;
        filename[0] = 0;
        Pos         = 0L;
        Write       = false;
    }
    
    // Datei schlieXen & aufrXumen
    PQXFile::~PQXFile(void)
    {
        if (f) fclose(f);
    }
    
    // Datei erzeugen und Header schreiben
    void PQXFile::WriteFile(const char *a_filename, PQXFileHeader *a_pfh)
    {
        Write = true;
        f = fopen(a_filename, "wb");
    
        strcpy(filename, a_filename);
    
        // Kennung im Header ergXnzen
        strcpy(a_pfh->ID, "PQX11");
    
        // Header schreiben
        if (f)
        {
            fwrite(&a_pfh->ID, 6*sizeof(char), 1, f);
            fwrite(&a_pfh->SampleFrequency, sizeof(a_pfh->SampleFrequency), 1, f);
            fwrite(&a_pfh->PointsPerBlock, sizeof(a_pfh->PointsPerBlock), 1, f);
            fwrite(&a_pfh->StartTime, sizeof(a_pfh->StartTime), 1, f);
        }
    
        // Wir behalten eine Kopie im Speicher, und vermerken Position
        memcpy(&pfh, a_pfh, sizeof(PQXFileHeader));
        Pos = ftell(f);
    }
    
    // Datenblock schreiben
    void PQXFile::WriteBlock(PQXBlockHeader *a_pbh, PQXData *data)
    {
        int i;
    
        fwrite(&a_pbh->TimeStamp, sizeof(a_pbh->TimeStamp), 1, f);
        for (i = 0; i < 8; i++)
            fwrite(&a_pbh->Counter[i], sizeof(a_pbh->Counter[i]), 1, f);
        for (i = 0; i < 8; i++)
            fwrite(&a_pbh->DigitalIN[i], sizeof(a_pbh->DigitalIN[i]), 1, f);
    
        fwrite(data, PQXDataSize * pfh.PointsPerBlock, 1, f);
    }
    
    // Datei zum Lesen Xffnen
    void PQXFile::OpenFile(char *a_filename)
    {
        Write = false;
        f = fopen(a_filename, "rb");
        strcpy(filename, a_filename);
        if (f)
        {
            // Head einlesen
            fread(&pfh.ID, 6*sizeof(char), 1, f);
            fread(&pfh.SampleFrequency, sizeof(pfh.SampleFrequency), 1, f);
            fread(&pfh.PointsPerBlock, sizeof(pfh.PointsPerBlock), 1, f);
            fread(&pfh.StartTime, sizeof(pfh.StartTime), 1, f);
    //        fread(&pfh.Reserved, sizeof(pfh.Reserved), 1, f);
    
            // Aktuelle Position merken
            Pos = ftell(f);
    
            // Ans Ende gehen & LXnge lesen
            fseek(f, 0, SEEK_END);
            Length = ftell(f);
    
            // UrsprXngliche Position wiederherstellen
            fseek(f, Pos, SEEK_SET);
    
            // Ersten Block-Header einlesen
            GotoBlock(0);
        }
    }
    
    // DateigrXXe in Bytes
    long PQXFile::GetFileSize(void)
    {
        if (!f || Write)
            return 0L;
    
        return Length;
    }
    
    // Anzahl der Blocks im File liefern
    long PQXFile::GetNoOfBlocks(void)
    {
        if (!f || Write)
            return 0L;
    
        // RXckgabewert berechnen
        return (Length - PQXFileHeaderSize) /
               (pfh.PointsPerBlock * PQXDataSize + PQXBlockHeaderSize);
    }
    
    // Werte aus File-Header zurXckgeben
    double PQXFile::GetSampleFrequency(void)
    {
        if (!f || Write)
            return 0.0;
        return pfh.SampleFrequency;
    }
    long PQXFile::GetPointsPerBlock(void)
    {
        if (!f || Write)
            return 0L;
        return pfh.PointsPerBlock;
    }
    time_t PQXFile::GetStartTime(void)
    {
        if (!f || Write)
            return 0;
        return pfh.StartTime;
    }
    char *PQXFile::GetStartTimeString(void)
    {
        if (!f || Write)
            return 0;
        char *s = ctime(&pfh.StartTime);
        s[strlen(s)-1] = '\0'; // abschlieXendes newline entfernen
        return s;
    }
    
    // Aktuelle Position in Datei ermitteln
    long PQXFile::GetBlockNo(void)
    {
        if (!f || Write)
            return 0L;
        return (Pos - PQXFileHeaderSize - PQXBlockHeaderSize) /
               (pfh.PointsPerBlock * PQXDataSize + PQXBlockHeaderSize);
    }
    
    // Zu bestimmtem Block gehen
    void PQXFile::GotoBlock(long BlockNo)
    {
        int i;
    
        if (!f || Write || BlockNo >= GetNoOfBlocks() || BlockNo < 0)
            return;
    
        // Neue Position ausrechnen
        Pos = BlockNo * (pfh.PointsPerBlock * PQXDataSize + PQXBlockHeaderSize)
              + PQXFileHeaderSize;
        fseek(f, Pos, SEEK_SET);
    
        // Block-Header einlesen
        fread(&pbh.TimeStamp, sizeof(pbh.TimeStamp), 1, f);
        for (i = 0; i < 8; i++)
            fread(&pbh.Counter[i], sizeof(pbh.Counter[i]), 1, f);
        for (i = 0; i < 8; i++)
            fread(&pbh.DigitalIN[i], sizeof(pbh.DigitalIN[i]), 1, f);
    //     fread(&pbh.Reserved, sizeof(pbh.Reserved), 1, f);
    
        // Neue Position speichern
        Pos = ftell(f);
    }
    
    // Daten lesen
    void PQXFile::ReadData(PQXData *data)
    {
        if (!f || Write)
            return;
    
        // Wir stehen direkt vor Daten, daher direkt lesen
        fread(data, PQXDataSize * pfh.PointsPerBlock, 1, f);
    
        // ZurXck gehen auf Datenanfang
        fseek(f, - long(PQXDataSize * pfh.PointsPerBlock), SEEK_CUR);
    
        Pos = ftell(f);
    }
    void PQXFile::ReadDataAndStepForward(PQXData *data)
    {
        int i;
    
        if (!f || Write)
            return;
    
        // Wir stehen direkt vor Daten, daher direkt lesen
        fread(data, PQXDataSize * pfh.PointsPerBlock, 1, f);
    
        // Jetzt Header des nXchsten Blocks einlesen
        fread(&pbh.TimeStamp, sizeof(pbh.TimeStamp), 1, f);
        for (i = 0; i < 8; i++)
            fread(&pbh.Counter[i], sizeof(pbh.Counter[i]), 1, f);
        for (i = 0; i < 8; i++)
            fread(&pbh.DigitalIN[i], sizeof(pbh.DigitalIN[i]), 1, f);
    //     fread(&pbh.Reserved, sizeof(pbh.Reserved), 1, f);
    
        // Dateiende Xberschritten? Dann einen zurXck.
        if (feof(f))
        {
            fseek(f, - long(PQXDataSize * pfh.PointsPerBlock +
                            PQXBlockHeaderSize), SEEK_END);
                fread(&pbh.DigitalIN[i], sizeof(pbh.DigitalIN[i]), 1, f);
    //         fread(&pbh.Reserved, sizeof(pbh.Reserved), 1, f);
        }
    
        Pos = ftell(f);
    }
    
    // Daten aus Block-Header
    clock_t PQXFile::GetTimeStamp(void)
    {
        if (!f || Write)
            return 0;
        return pbh.TimeStamp;
    }
    double PQXFile::GetTimeStampSeconds(void)
    {
        return double(GetTimeStamp()) / double(CLOCKS_PER_SEC);
    }
    long PQXFile::GetCounter(int No)
    {
        if (!f || Write)
            return 0;
        return pbh.Counter[No];
    }
    char PQXFile::GetDigitalIN(int No)
    {
        if (!f || Write)
            return 0;
        return pbh.DigitalIN[No];
    }
    
    char *PQXFile::GetFileName(void)
    {
        return filename;
    }
    
    long PQXFile::EstimateFileSize(long PointsPerBlock, long NoOfBlocks)
    {
        return PQXFileHeaderSize + NoOfBlocks * (PQXBlockHeaderSize +
                    PointsPerBlock * PQXDataSize);
    }
    

    Ich hoffe Du fühlst Dich jetzt nicht erschlagen von so viel Code! 🙄
    Und wahrscheinlich ist das wieder nicht so super geschrieben, bzw. programmiert, aber ich kanns leider nicht ändern! 😞
    Ich kann ja nichtmal zwischen c und c++-code unterscheiden!



  • Da hammas doch. Die ganzen longs, die hier drin stehen sind unter amd64 mit dem gcc doppelt so lang wie auf normalen x86ern. Deshalb wird der Header falsch gelesen. Wenn du sie alle in int änderst, sollte es unter 64-Bit funktionieren. Eine schöne Lösung ist das aber nicht, eher ein "amd64-Hack". Besser wären einige typedefs am Anfang für diese Typen.



  • .filmor schrieb:

    Da hammas doch. Die ganzen longs, die hier drin stehen sind unter amd64 mit dem gcc doppelt so lang wie auf normalen x86ern. Deshalb wird der Header falsch gelesen. Wenn du sie alle in int änderst, sollte es unter 64-Bit funktionieren. Eine schöne Lösung ist das aber nicht, eher ein "amd64-Hack". Besser wären einige typedefs am Anfang für diese Typen.

    mit -m32 sollte sich das Problem aber von selbst geleost haben, oder? 😕



  • Na da bin ich aber gespannt. Ich aender das gleich mal! Obwohl ich da nicht sicher bin, ob es wirklich daran liegt, da ich mir die ausgelesenen Daten vom Header am Anfang nochmal anzeigen lasse. Und die sind immer korrekt. JEdenfalls wenn ich mit -m32 kompiliere. Ohne -m32 werden die seltsamer Weise garnicht angezeigt und das Programm höddelt so weiter.

    @ Blue-Tiger,

    nee, hat es nicht wirklich gebracht. S.o. Das Programm macht auch mit dem -m32-flag nicht was es wirklich soll! Und wie gesagt, am eigentlichen Code kann es nicht liegen, da es ja auf nem Pentium 4, 32-bit System, läuft.



  • @ .filmor

    Du hattest total recht! Es liegt wohl wirklich daran, dass er den HEader nicht korrekt liest.
    Ich habe jetzt folgendes probiert:
    Zunächst habe ich mal alle long in int verwandelt => keine Änderung.
    Dann habe ich mal den kompletten Header-Ausleseteil auskommentiert und die Daten, also Frequenz und (wohl am wichtigsten) die Punkte pro Datenblock, direkt eingegeben. Das Programm habe ich dann mit -m32-flag kompiliert. Es läuft!!!
    Also muss es wirklich ein Problem mit dem Auslesen sein. Aber wo kann da genau ein Fehler passieren?

    // PQXFileHeader fuellen - Werte aus Header in .dat!
            std::string datei;
            int sf, enter;
            int ppb;
    
           char cfindText[8];
           int m;
           FILE *File;
    
            cout << "Dateiname: ";
            getline(cin, datei);
    
          // Daten aus Header lesen
    
          File = fopen(datei.c_str(), "r");
    
          for(m = 0; m < 10; m++)
          {
              cfindText[m] = fgetc(File);
          }
          while(!feof(File))
          {
              if(!strcmp(cfindText, "of Points: "))
              {
                fscanf(File, "%i", &ppb);
                cout << "Points per spectrum: " << ppb <<"\n";
              }
              if(!strcmp(cfindText, "Frequency:"))
              {
                fscanf(File, "%i", &sf);
                cout << "Frequency: " << sf <<"\n";
              }
              for(m = 0; m < 9; m++)
              {
                cfindText[m] = cfindText[m+1];
              }
              cfindText[9] = fgetc(File);
          }
          fclose(File);
    

    Soweit ich das verstehe werden hier lediglich int Variablen ausgelesen, also ppb und sf.
    Um mal einen Einblick in den Header zu geben habe ich mir mal erlaubt auch den zu posten:

    # PiezoQEXAFS ASCII File
    #
    # Generated by pqx2dat Ver 1.3 / B. Griesebock, 2004
    #
    # Original File: cuzno1_02.pqx
    #          Date: Mon Oct 11 02:59:36 2004
    # No of Spectra: 15987
    #  No of Points: 1990
    #     Frequency: 10000.000000 Hz
    #
    # Averaging:     over 1 spectra and 1 points
    #                yielding 15987 spectra a 1990 points
    #
    # Output is as voltage.
    # Spectra are separated by two blank lines.
    #
    # Columns:
    # Channel 0, Channel 1, Channel 2, Channel 3,
    #
        5.2814     0.6354     0.1770     4.0256
    

    ..wobei die letzte Zeile bereits die erste Zeile des Datenblocks ist.
    Also was könnte im 64-bit System veranlassen, dass die "1990" bzw. "10000" nicht korrekt gelesen werden?



  • EagleFox schrieb:

    Und wie gesagt, am eigentlichen Code kann es nicht liegen, da es ja auf nem Pentium 4, 32-bit System, läuft.

    reiner zufall.

    char cfindText[8];
    // ...
          for(m = 0; m < 10; m++)
          {
              cfindText[m] = fgetc(File);
          }
    
    // ...
              for(m = 0; m < 9; m++)
              {
                cfindText[m] = cfindText[m+1];
              }
              cfindText[9] = fgetc(File);
    

    passt irgendwie nicht. mach mal ein

    char cfindText[10];
    

    draus.

    edit: dann kann es allerdings trotzdem nicht funktionieren.

    char cfindText[11] = {};
           int m;
           FILE *File;
    
            cout << "Dateiname: ";
            getline(cin, datei);
    
          // Daten aus Header lesen
    
          File = fopen(datei.c_str(), "r");
    
          while(!feof(File))
          {
              if(!strncmp(cfindText, "of Points: ",11))
              {
                fscanf(File, "%i", &ppb);
                cout << "Points per spectrum: " << ppb <<"\n";
              }
              if(!strncmp(cfindText+1, "Frequency:",10))
              {
                fscanf(File, "%i", &sf);
                cout << "Frequency: " << sf <<"\n";
              }
              std::copy(cfindText+1, cfindText+11, cfindText);
              cfindText[10] = fgetc(File);
          }
          fclose(File);
    


  • ES LÄUFT!!!!!!!!!!!!!!!!!!!!!!!

    Yiepppppppiiiiiiiiiiieeeeeeeeeeehhhhhhhhhh!!!!!!!!!!!!!!!!!!!!

    Sorry für den unkontrollierten Ausbruch der Heiterkeit!

    Kannst Du mir vielleicht noch in ein bis eineinhalb Sätzen sagen, was Du da genau verändert hast? Also rein kryptisch kann ich das erkennen, aber was ist der Hintergrund? (Ich spreche doch nicht so gut c++, bin da eher in perl bewandert)

    Bitte erlaubt mir an dieser Stelle noch eine kurze Frage:

    Wie kann ich den Dateinamen direkt aus einem Eingabeparameter auslesen?

    Ich stelle mir in etwa sowas vor:

    Programmstart:

    # ./programm dateiname
    

    dann als code am Anfang des Programms:

    if(!defined $ARGV[0]) #das wäre perl, also: wenn kein Eingabeparameter definiert ist, dann
    {
        cout << "Dateiname: ";
        cin >> datei;
    }
    else
    {
        $datei = $ARGV[0] #wieder perl, also : datei = "Eingabeparameter";
    }
    

    Ich danke Euch allen schon mal tausendfach für die super Hilfe und Geduld, die Ihr mit mir hattet!


Anmelden zum Antworten