从 .dat 二进制文件中读取数据
Reading data from a .dat binary file
我有一个 .dat 文件需要读取并为人们打印记录
具有指定为命令行参数的属性。文件格式如下。每个人的记录都以一个无符号的 32 位整数开头,其中包含有关此人的各种信息:
位数
0-4 : 名字的长度 (key=first)
5-9 : 中间名的长度 (key=middle)
10-14 : 姓氏的长度 (key=last)
15-21 岁:年龄(关键=年龄)
22:性别(0=男,1=女)(键=性别)
23-28 : state (0 to 49 in alphabet order) (key=state)
29 : 目前已婚 (0=false, 1=true) (key=married)
30 : 全职工作 (0=false, 1=true) (key=employed)
31 : 上过大学 (0=false, 1=true) (key=college)
我想我应该先读取整个 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;
}
这是未经测试的,但希望能让您了解 "mask and shift" 技术。您可以阅读更多相关信息:
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;
#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] = {'[=10=]'};
...
// 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";
};
我有一个 .dat 文件需要读取并为人们打印记录 具有指定为命令行参数的属性。文件格式如下。每个人的记录都以一个无符号的 32 位整数开头,其中包含有关此人的各种信息:
位数
0-4 : 名字的长度 (key=first)
5-9 : 中间名的长度 (key=middle)
10-14 : 姓氏的长度 (key=last)
15-21 岁:年龄(关键=年龄)
22:性别(0=男,1=女)(键=性别)
23-28 : state (0 to 49 in alphabet order) (key=state)
29 : 目前已婚 (0=false, 1=true) (key=married)
30 : 全职工作 (0=false, 1=true) (key=employed)
31 : 上过大学 (0=false, 1=true) (key=college)
我想我应该先读取整个 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;
}
这是未经测试的,但希望能让您了解 "mask and shift" 技术。您可以阅读更多相关信息: 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;
#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] = {'[=10=]'};
...
// 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";
};