machen Compiler Unterschiede zwischen 32bit und 64bit-Systemen?
-
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!