从.dat二进制文件中读取数据

时间:2015-04-20 15:47:40

标签: c file binaryfiles fread

我需要读取.dat文件并为人们打印记录 具有指定为命令行参数的属性。文件格式如下。每个人的记录都以一个无符号的32位整数开头,该整数包含有关该人的各种信息:

0-4:名字长度(键=第一个)

5-9:中间名长度(键=中)

10-14:姓氏长度(key = last)

15-21:年龄(关键=年龄)

22:性别(0 =男性,1 =女性)(关键=性别)

23-28:状态(按字母顺序排列0到49)(键=状态)

29:目前结婚(0 =假,1 =真)(关键=已婚)

30:全职工作(0 =假,1 =真)(关键=就业)

31:上大学(0 =假,1 =真)(关键=大学)

我想我首先要读取整个32位(4字节),然后从32位整数中逐位读取。我是fread和fseek的新手,所以我真的不知道自己是否走在正确的轨道上,任何帮助都将受到赞赏。到目前为止,这是我的代码。

  int main(int argc, char *argv[]) {

  char *buf;
  long lSize;
  size_t result;

  FILE *fp;
  fp = fopen("/u1/junk/people.dat","r");
  if(fp == NULL) {
    printf("Error: can't open file to read\n");
    return -1;
  }
  else {
    printf("File people.dat opened successfully to read\n");
  }


  //obtian file size
  fseek(fp, 0, SEEK_END);
  lSize = ftell(fp);
  rewind(fp);

  //allocate memory to contain the whole file
  buf = (char*) malloc (sizeof(char)*lSize);

  while (!feof(fp)) {
    fread(buf, 4, 1, fp);
    fseek(fp, i, SEEK_CUR);
    fread(buf, 32, 1, fp);
    printf("%s\n", buf);
    i+=32;
  }

  fclose(fp);
  return 0;  
}

2 个答案:

答案 0 :(得分:1)

这是未经测试的,但希望能让您了解“蒙版和移位”技术。您可以阅读更多相关信息: What are bitwise shift (bit-shift) operators and how do they work?Bitfield manipulation in C

假设你读取无符号的32位整数:

unsigned long myint;
fread(&myint, sizeof(myint), 1, fid);

现在,使用shift和mask来拉出值。

// bits 0-4 (5 bits)
unsigned long firstNameLength = myint & 0xF1;

// bit 31
unsigned long attendedCollege = (myint & 0x0000000E) << 31;

答案 1 :(得分:1)

#include <stdio.h>

// define first 32 bits of record
struct personRecord
{
    unsigned first    :5;
    unsigned middle   :5;
    unsigned last     :5;
    unsigned age      :7;
    unsigned sex      :1;
    unsigned state    :6;
    unsigned married  :1;
    unsigned employed :1;
    unsigned college  :1;
};

// prototypes
void processRecord(FILE* fp, char* buf);


int main(int argc, char *argv[])
{

    struct personRecord key;

    FILE *fp;
    fp = fopen("/u1/junk/people.dat","r");
    if(fp == NULL)
    {
        printf("Error: can't open file to read\n");
        return -1;
    }

    // implied else, fopen successful

    printf("File people.dat opened successfully to read\n");



    while ( 1 == fread( &key, 4, 1, fp ) )
    {
        processRecord(fp, key);
    }

    fclose(fp);
    return 0;
} // end function: main



void processRecord(FILE* fp, personRecord key)
{
      int result;
      int bufFirst[key.first] = {'\0'};
      ...

      // use  lengths to determine how much more  bytes to read for each field
      result = fread( bufFirst, key.first, 1, fp );
      if ( result == key.first )
      { // then successful acquire first name
          ...
      }
      ...
      // first, middle, last,

      // use lookup table to get state name from state field
      char * pState = alphabeticalState[key.state];

      // do something with the extracted info
      ...
} // end function: processRecord


const char * alphabeticalStates[] =
{
    "alabama";
    ...
    "washington";
    "wisconsin";
};