我有一个带有可变长度记录的二进制文件,看起来像这样:
12 economic10
13 science5
14 music1
15 physics9
16 chemistry9
17 history2
18 anatomy7
19 physiology7
20 literature3
21 fiction3
16 chemistry7
14 music10
20 literature1
课程名称是文件中唯一的可变长度记录,第一个数字是课程的代码,它可以是1到9999之间的数字,第二个数字是部门,它可以在1之间和10。 正如您在文件中看到的那样,课程名称和部门编号之间没有空格。
问题是如何从二进制文件中读取?文件中没有字段告诉我字符串的大小是什么,课程名称是什么。 我可以读第一个int(课程ID),但我怎么知道课程名称的大小?
答案 0 :(得分:3)
将fscanf()
与格式字符串"%u %[a-z]%u"
一起使用。
这是一个完整的示例程序:
#include <stdio.h>
#define NAME_MAX 64
int main(int argc, char ** argv)
{
FILE * file = fopen("foo.txt", "rb");
unsigned int course, department;
char name[NAME_MAX];
while(fscanf(file, "%u %[a-z]%u", &course, name, &department) != EOF)
{
// do stuff with records
printf("%u-%u %s\n", department, course, name);
}
fclose(file);
return 0;
}
答案 1 :(得分:1)
正如其他人所说,这看起来很像文本,因此文本解析方法可能是正确的方法。由于这是家庭作业,我不会为你编写代码,但这是我采取的一般方法:
答案 2 :(得分:0)
要读取可变长度记录,您应该使用某种约定。例如,表示记录结束的特殊字符。在每条记录中,您可以使用另一个指示字段结尾的特殊字符。
DO_READ read from file
is END_OF_RECORD char present?
yes: GOTO DO_PROCESS
no : GOTO DO_READ
DO_PROCESS read into buffer
is END_OF_FILE mark present?
yes: GOTO DOSOMETHINGWITHIT
no: GOTO DO_PROCESS
答案 3 :(得分:0)
您首先需要知道文件是如何写出来的。
答案 4 :(得分:0)
如果课程代码和课程名称(包括部门代码)之间存在一对一的对应关系,您可以从代码中推断出课程名称的大小,在代码或配置文件中的某个位置使用预定义的表格。
如果没有,我看到的主要问题是区分music1
和music10
等内容。
答案 5 :(得分:0)
假设没有回车符,并且每个字符串都以空值终止。 我写了一个小程序来创建一个二进制文件,然后再读回来,产生类似的输出。
// binaryFile.cpp
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#define BUFSIZE 64
int _tmain(int argc, _TCHAR* argv[])
{
FILE *f;
char buf[BUFSIZE+1];
// create dummy bin file
f = fopen("temp.bin","wb");
if (f)
{ // not writing all the data, just a few examples
sprintf(buf,"%04d%s\00",12,"economic10"); fwrite(buf,sizeof(char),strlen(buf)+1,f);
sprintf(buf,"%04d%s\00",13,"science5"); fwrite(buf,sizeof(char),strlen(buf)+1,f);
sprintf(buf,"%04d%s\00",14,"music1"); fwrite(buf,sizeof(char),strlen(buf)+1,f);
sprintf(buf,"%04d%s\00",15,"physics9"); fwrite(buf,sizeof(char),strlen(buf)+1,f);
fclose(f);
}
// read dummy bin file
f = fopen("temp.bin","rb");
if (f)
{
int classID;
char str[64];
char *pData
long offset = 0;
do
{
fseek(f,offset,SEEK_SET);
pData = fgets(buf,BUFSIZE,f);
if (pData)
{ sscanf(buf,"%04d%s",&classID,&str);
printf("%d\t%s\r\n",classID,str);
offset +=strlen(pData)+1; // record + 1 null character
}
} while(pData);
fclose(f);
}
getchar();
return 0;
}