我需要读取.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;
}
答案 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";
};