如何从文件中读取不同大小的位值?

时间:2016-12-27 20:55:04

标签: c++ file fread

我正在从文本文件中读取一堆二进制值,因为我使用fwrite存储它们。问题是文件中的第一个值大小为5个字节,接下来的4800个值大小为2个字节。因此,当我尝试遍历文件并读取值时,它会给我错误的结果,因为我的程序不知道它应该第一次占用5个字节,然后是剩余的4800次占用2个字节。

以下是我在文件中循环的方法:

long lSize;
unsigned short * buffer;
size_t result;

pFile = fOpen("dataValues.txt", "rb");

lSize = ftell(pFile);

buffer = (unsigned short *) malloc (sizeof(unsigned short)*lSize);    
size_t count = lSize/sizeof(short);



for(size_t i = 0; i < count; ++i)
{
   result = fread(buffer+i, sizeof(unsigned short), 1, pFile);
   print("%u\n", buffer[i]);
 }

我很确定我需要更改fread语句,因为第一个值是time_t类型所以我可能需要一个如下所示的语句:

result = fread(buffer+i, sizeof(time_t), 1, pFile);

然而,当我尝试它时,这不起作用,我认为这是因为我没有正确改变起始位置。我认为虽然我确实读了5个字节的数据,但我没有足够的移动起始位置。

这里有没有人对fread有很好的理解?你能否让我知道我可以改变什么来让我的计划完成我所需要的。

修改

这就是我写文件的方式。

fwrite(&timer, sizeof(timer), 1, pFile);
fwrite(ptr, sizeof(unsigned short), rawData.size(), pFile);

EDIT2:

我尝试使用ifstream

读取文件
int main()
{
    time_t x;
    ifstream infile;
    infile.open("binaryValues.txt", ios::binary | ios::in);
    infile.read((char *) &x, sizeof(x));
    return 0;
}

然而,现在它没有编译,只是给我一堆undefined reference to错误代码,我甚至没有写过。

2 个答案:

答案 0 :(得分:2)

我没有看到问题:

uint8_t five_byte_buffer[5];
uint8_t two_byte_buffer[2];
//...
ifstream my_file(/*...*/);
my_file.read(&five_byte_buffer[0], 5);
my_file.read(&two_byte_buffer[0], 2);

那么,您的具体问题是什么?

编辑1:循环阅读

while (my_file.read(&five_byte_buffer[0], 5))
{
  my_file.read(&two_byte_buffer[0], 5);
  Process_Data();
}

答案 1 :(得分:0)

你不能。流是字节,几乎总是以八位字节(8位字节)为导向。

您可以轻松地在其上构建面向比特的流。您只需在缓冲区中保留几个字节,并跟踪哪个位是当前的。注意获取最后几位,并尝试将字节访问与位访问混合。

未经测试,但这是一般的想法。

  struct bitstream
  {
      unsigned long long rack;  // 64 bits rack
      FILE *fp;                 // file opened for reading
      int rackpos;              // 0 - 63, poisition of bits read.
  }

  int getbits(struct bitstream *bs, int Nbits)
  {
     unsigned long long mask = 0x8000 0000 0000 0000;
     int answer = 0;

     while(bs->rackpos > 8)
     {
        bs->rack <<= 8;
        bs->rack |= fgetc(bs->fp);
        bs->rackpos -= 8;
     }
     mask >>= bs->rackpos;
     for(i=0;i<Nbits;i++)
     {
        answer <<= 1;
        answer |= bs->rack & mask;
        mask >>= 1;
     }
     bs->rackpos += Nbits;

     return answer;
  }

您需要决定如何知道流终止的时间。因为你会用fgetc()读取EOF来破坏最后几位。