Zostałem poproszony o pomoc w odczytaniu plików, będących zapisem pewnych pomiarów w programie catman firmy HBM Messtechnik. Wskutek pomyłki lub niedopatrzenia część danych została zapisana w formacie binarnym zamiast w formacie tekstowym.
Dane zapisane w formacie binarnym zawierają się w dwu plikach: plik xxxx.HDR jest opisem struktury danych w postaci czystego tekstu, plik xxxx.DAT jest ciągiem danych binarnych.
Zawartość pliku HDR jest następująca:
HBM_MESSTECHNIK_DARMSTADT_DATAFILE
%GLOINFO_BEGIN
DATE=09/15/11
TIME=12:01:55
%GLOINFO_END
%CHANINFO_BEGIN
TITLE=nazwa_serii
UNIT=N
IDENT=
LEN=900
DATAFILE=xxxx.DAT
FORMAT=HBM_BINARY
STORAGE=CHANNEL
VALSIZE=8
STARTPTR=0
%CHANINFO_END
[inna seria]
%CHANINFO_BEGIN
TITLE=Temperatura
UNIT=°C
IDENT=
LEN=900
DATAFILE=xxxx.DAT
FORMAT=HBM_BINARY
STORAGE=CHANNEL
VALSIZE=8
STARTPTR=1800
%CHANINFO_END
[inne serie]
Z analizy pliku HDR wiedziałem więc, co siedzi w pliku dat (900-elementowe serie po 8 bajtów/element), tylko pytanie - w jakim formacie dane te były zapisane. Na szczęście dostałem też pliki wynikowe zapisane w formacie tekstowym, zatem wiedziałem, jakich wartości mogę się spodziewać. Domyślałem się, że jest to jakiś zapis binarny liczb zmiennoprzecinkowych, ale dawno tego nie praktykowałem, trzeba było sobie odświeżyć informacje. Ale poszło z górki: przy pomocy konwertera liczb z zapisu dziesiętnego na zapis binarny w standardzie IEEE-754 sprawdziłem, jak wyglądają oczekiwane wartości w zapisie heksadecymalnym. Potem musiałem przypomnieć sobie, jak się programuje w C, i w efekcie powstał przytoczony niżej mały potworek programistyczny, dzięki któremu zarobiłem na flaszkę^W wyrazy wdzięczności ;-)
Ponieważ wszystkie pliki miały tę samą strukturę, więc nie chciało mi się pisać parsera pliku .HDR.
#include <stdio.h>
double d;
double dane[5400];
/* 5400 bo było 6 serii po 900 elementów */
FILE * fd;
int k, maxk;
/* pierwszy i jedyny wymagany parametr to nazwa pliku .DAT. Dane wyjściowe wysyłane są na STDOUT */
main(int argc, char *argv[]) {
fd = fopen(argv[1],"rb");
for (k=0 ; k < 5400 ; k++) {
fread(&d,8,1,fd);
dane[k] = d;
if (feof(fd)) {
/* a to po to, że jedna seria była krótsza */
maxk = k;
k = 5400;
}
maxk = (maxk+1)/6;
}
fclose(fd);
for (k=0 ; k < maxk ; k++) {
printf("%12.5f%12.5f%12.5f%12.4f%12.4f%12.4f\n",
dane[k],dane[maxk+k],dane[2*maxk+k],dane[3*maxk+k],dane[4*maxk+k],dane[5*maxk+k]);
}
}
Najpopularniejsze wpisy:
- [2019-01-15] Wskaźniki cen towarów i usług konsumpcyjnych (inflacja): średnioroczne w latach 2007-2018 oraz w poszczególnych miesiącach lat 2008-2018
- [2011-09-04] Kalendarz na rok 2012
- [2012-03-03] Kalendarz na rok 2013 w wersji PNG i PDF
- [2010-11-26] Kalendarz na rok 2011 ze Świętem Trzech Króli (6 stycznia)
- [2013-12-28] Kalendarz na rok 2014 - gratis - do wydrukowania itp.
Najpopularniejsze wpisy z wieloma wersjami:
- Wskaźniki cen towarów i usług konsumpcyjnych (inflacja): średnioroczne w latach 2007-2018 oraz w poszczególnych miesiącach lat 2008-2018
- Kalendarz na rok 2014 - gratis - do wydrukowania itp.
- Oprocentowanie wybranych kont oszczędnościowych oraz lokat jednodniowych w bankach w Polsce
- System Informacji Oświatowej (SIO) - raport wg stanu na 10 września 2011 i 30 września 2011
- 4,0196 zł - kurs euro dla zamówień publicznych (przetargów) od 1 stycznia 2012 roku
Dodaj komentarz