将dat文件转换为数字

convert dat file to numbers

我有一个 dat 文件,我只想从中提取数字。 我用 c++ 写了一段代码,但我不知道如何将 char 数组转换为可读的数字。

下面第24页的link里面可以看到dat的使用说明。文件: http://www.psi.ch/drs/DocumentationEN/manual_rev50.pdf (我只需要时间和电压数字)。

这是我的尝试:

#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

int main()
{

ifstream InpData;
char filename[256];
cout<<"Enter file name:"<<endl;
cin>>filename;
InpData.open(filename,ios_base::binary);
while(InpData==0)
{
    cout<<"You entered wrong address, enter again file name:"<<endl;
    cin>>filename;
    InpData.open(filename,std::ifstream::binary);
}
InpData.seekg (0, InpData.end);
int length = InpData.tellg();
InpData.seekg (0, InpData.beg);

char *buffer=new char[length];

ofstream Outpdata;
Outpdata.open("results.txt");
    std::cout << "Reading " << length << " characters... ";
    InpData.read(buffer,length);
    if (InpData)
    {
         std::cout << "all characters read successfully."<<endl;
        int c=0;
         for(int i=0; i<1024; i++)
         {
             for(int j=((i*4)+12); j<((i*4)+12)+4; j++)
             {
                Outpdata<<buffer[j];

             }
             Outpdata<<endl;
         }
    }

    else
      std::cout << "error: only " << InpData.gcount() << " could be read";
    InpData.close();
    Outpdata.close();

    delete[] buffer;


  }


}

如您所见,输出数据文件如下所示:

•«>

[¬^>

‰~

等等...

我该怎么办? 谢谢!

更新:

这是我的新代码:

#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
using namespace std;

    int main()
{ 

    ifstream InpData;
    char filename[256];
cout<<"Enter file name:"<<endl;
cin>>filename;
InpData.open(filename,ios_base::binary);
while(InpData==0)
{
    cout<<"You entered wrong address, enter again file name:"<<endl;
    cin>>filename;
    InpData.open(filename,std::ifstream::binary);
}
InpData.seekg (0, InpData.end);
int length = InpData.tellg();
char *buffer=new char[length];
    std::cout << "Reading " << length << " characters... ";
InpData.seekg (0, InpData.beg);
InpData.read(buffer,length);
ofstream Outpdata;
Outpdata.open("results.txt");

 for(size_t i = 0; i < 1024; ++i)
{
    size_t off = i * 4 + 12;
    // parse a 32bit integer little-endian
    int32_t value = ((int32_t)(unsigned char)buffer[off + 3] << 24)
                 | ((int32_t)(unsigned char)buffer[off + 2] << 16)
                  | ((int32_t)(unsigned char)buffer[off + 1] << 8)
                | ((int32_t)(unsigned char)buffer[off + 0] << 0);
                Outpdata<<value<<endl;
             }
            InpData.close();
            Outpdata.close();
            delete[] buffer;*/
             }

我仍然只得到零....

read_binary.cpp:

/*
   Name:           read_binary.cpp
   Created by:     Stefan Ritt <stefan.ritt@psi.ch>
   Date:           July 30th, 2014

   Purpose:        Example file to read binary data saved by DRSOsc.

   Compile and run it with:

      gcc -o read_binary read_binary.cpp

      ./read_binary <filename>

   This program assumes that a pulse from a signal generator is split
   and fed into channels #1 and #2. It then calculates the time difference
   between these two pulses to show the performance of the DRS board
   for time measurements.

   $Id: read_binary.cpp 21495 2014-09-26 14:20:49Z ritt $
*/

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

typedef struct {
   char           time_header[4];
   char           bn[2];
   unsigned short board_serial_number;
} THEADER;

typedef struct {
   char           event_header[4];
   unsigned int   event_serial_number;
   unsigned short year;
   unsigned short month;
   unsigned short day;
   unsigned short hour;
   unsigned short minute;
   unsigned short second;
   unsigned short millisecond;
   unsigned short range;
   char           bs[2];
   unsigned short board_serial_number;
   char           tc[2];
   unsigned short trigger_cell;
} EHEADER;

/*-----------------------------------------------------------------------------*/

int main(int argc, const char * argv[])
{
   THEADER th;
   EHEADER eh;
   char hdr[4];
   unsigned short voltage[1024];
   double waveform[4][1024], time[4][1024];
   float bin_width[4][1024];
   int i, j, ch, n, chn_index;
   double t1, t2, dt;
   char filename[256];

   int ndt;
   double threshold, sumdt, sumdt2;

   if (argc > 1)
      strcpy(filename, argv[1]);
   else {
      printf("Usage: read_binary <filename>\n");
      return 0;
   }

   // open the binary waveform file
   FILE *f = fopen(filename, "r");
   if (f == NULL) {
      printf("Cannot find file \'%s\'\n", filename);
      return 0;
   }

   // read time header
   fread(&th, sizeof(th), 1, f);
   printf("Found data for board #%d\n", th.board_serial_number);

   // read time bin widths
   memset(bin_width, sizeof(bin_width), 0);
   for (ch=0 ; ch<5 ; ch++) {
      fread(hdr, sizeof(hdr), 1, f);
      if (hdr[0] != 'C') {
         // event header found
         fseek(f, -4, SEEK_CUR);
         break;
      }
      i = hdr[3] - '0' - 1;
      printf("Found timing calibration for channel #%d\n", i+1);
      fread(&bin_width[i][0], sizeof(float), 1024, f);
   }

   // initialize statistics
   ndt = 0;
   sumdt = sumdt2 = 0;

    // loop over all events in the data file
   for (n= 0 ; ; n++) {
       // read event header
       i = (int)fread(&eh, sizeof(eh), 1, f);
      if (i < 1)
         break;

      printf("Found event #%d\n", eh.event_serial_number);

      // reach channel data
      for (ch=0 ; ch<5 ; ch++) {
         i = (int)fread(hdr, sizeof(hdr), 1, f);
         if (i < 1)
            break;
         if (hdr[0] != 'C') {
            // event header found
            fseek(f, -4, SEEK_CUR);
            break;
         }
         chn_index = hdr[3] - '0' - 1;
         fread(voltage, sizeof(short), 1024, f);

         for (i=0 ; i<1024 ; i++) {
            // convert data to volts
            waveform[chn_index][i] = (voltage[i] / 65536. + eh.range/1000.0 - 0.5);

            // calculate time for this cell
             for (j=0,time[chn_index][i]=0 ; j<i ; j++)
                time[chn_index][i] += bin_width[chn_index][(j+eh.trigger_cell) % 1024];
          }
      }


      // align cell #0 of all channels
      t1 = time[0][(1024-eh.trigger_cell) % 1024];
      for (ch=1 ; ch<4 ; ch++) {
         t2 = time[ch][(1024-eh.trigger_cell) % 1024];
         dt = t1 - t2;
         for (i=0 ; i<1024 ; i++)
            time[ch][i] += dt;
      }

      t1 = t2 = 0;
      threshold = 0.3;

      // find peak in channel 1 above threshold
      for (i=0 ; i<1022 ; i++)
         if (waveform[0][i] < threshold && waveform[0][i+1] >= threshold) {
            t1 = (threshold-waveform[0][i])/(waveform[0][i+1]-waveform[0][i])*(time[0][i+1]-time[0][i])+time[0][i];
           break;
         }

      // find peak in channel 2 above threshold
      for (i=0 ; i<1022 ; i++)
         if (waveform[1][i] < threshold && waveform[1][i+1] >= threshold) {
             t2 = (threshold-waveform[1][i])/(waveform[1][i+1]-waveform[1][i])*(time[1][i+1]-time[1][i])+time[1][i];
            break;
         }

       // calculate distance of peaks with statistics
      if (t1 > 0 && t2 > 0) {
         ndt++;
         dt = t2 - t1;
         sumdt += dt;
         sumdt2 += dt*dt;
      }
   }

   // print statistics
    printf("dT = %1.3lfns +- %1.1lfps\n", sumdt/ndt, 1000*sqrt(1.0/(ndt-1)*(sumdt2-1.0/ndt*sumdt*sumdt)));

   return 1;
}

您的数据采用小尾数法(引用:"LSB first",第 23 页底部)所以您可以:

for(size_t i = 0; i < 1024; ++i)
{
    size_t off = i * 4 + 12;
    // parse a 32bit integer little-endian
    int32_t value = ((int32_t)(unsigned char)buffer[off + 3] << 24)
                  | ((int32_t)(unsigned char)buffer[off + 2] << 16)
                  | ((int32_t)(unsigned char)buffer[off + 1] << 8)
                  | ((int32_t)(unsigned char)buffer[off + 0] << 0);
    ...
}

对于浮点数你可以使用 memcpy:

assert(sizeof(float)==4);
for(size_t i = 0; i < 1024; ++i)
{
    size_t off = i * 4 + 12;
    // parse a 32bit ieee floating point
    float value;
    memcpy(&value, buffer + off, 4);
    ...
}