2013-03-06 122 views
1

我是新来的,需要一些帮助。 :)从二进制文件(C)中读取非固定长度

我正在编写一个程序,它必须写入和读取二进制文件。我要听课添加到它,它们看起来像:

COURSECODE;COURSENAME;MAXAPPLICANTS;ACTUALAPPLICANTS; 

我可以写在一个文件,而无需使用char*任何问题。

我的问题是:如果记录是非固定大小,我该如何在结构中读取它? (例如:coursename可以是线性代数或分析 - >长度是未确定的)我还需要修改实际申请人编号,我如何找到它的字符位置和当前行?

我很乐意提出想法,我也很感激任何源代码,我用C++进行编程,C对我来说是一个艰难的后退。

预先感谢您!

+1

到目前为止,你有什么想法? – 2013-03-06 09:01:56

+1

你的例子似乎是一个文本文件,而不是一个二进制文件? – nos 2013-03-06 09:13:27

+0

为什么这是一个二进制文件? – 2013-03-06 09:15:57

回答

2

你的结构看起来像

struct student { 
char *coursecode; 
char *coursename; 
char *max_applicants; 
char *actual_applicants; 
}; 

只需将另一个成员添加到您的结构中,如int size即可存储结构的总大小。

当您从二进制文件中读取你应该阅读记录的第一4 bytes你会得到完整的尺寸,然后看看有多少个字符是有记录到每一次,读那么多和记号化字符串由;,你会发现你的记录。

+0

非常感谢! – Peter 2013-03-10 13:25:58

0

没有终止字符,这是不可能的。

如果您将一些字符分割为不同的数据,那么可能的话。例如,3个字符串可以通过其\ 0分开告知。所以你阅读直到\ 0,三次。

0

你可以读文件到char*缓冲区,然后更换任何;\0(字符串终止字符),最后是你拿的开始字段到你的结构的指针:

struct student { 
    char *coursecode; 
    char *coursename; 
    char *max_applicants; 
    char *actual_applicants; 
}; 

你可能首先需要用atoi解析数字字段。

0

建议#1:如果你是印地语并且你曾经重生过,那么从学习C开始,然后过渡到C++。

建议#2:所以如果我理解正确,你有四个字符串连在一起,用分号隔开。然后你可以使用strtok_r()分裂每一行,并把文件的内容结构的数组(所有错误检查省略清晰,但你绝对应该有一些):

typedef struct { 
    char *code; 
    char *name; 
    int max_appl; 
    int cur_appl; 
} Course; 

char buf[1024]; 

FILE *f = fopen("courses.txt", "r"); 

size_t size = 0; 
size_t allocsize = 8; 
Course *c = malloc(allocsize * sizeof(*c)); 

char *end; 

while (fgets(buf, sizeof(buf), f) != NULL) { 
    if (size >= allocsize) { 
     allocsize <<= 1; 
     c = realloc(c, allocsize * sizeof(*c)); 
    } 

    c[size].code = strdup(strtok_r(buf, ";", &end)); 
    c[size].name = strdup(strtok_r(NULL, ";", &end)); 
    c[size].max_appl = strtol(strtok_r(NULL, ";", &end), NULL, 10); 
    c[size].cur_appl = strtol(strtok_r(NULL, "\n", &end), NULL, 10); 

    size++; 
} 

int i; 
for (i = 0; i < size; i++) { 
    Course *p = c + i; 
    printf("%s\n%s\n%d\n%d\n\n", p->code, p->name, p->max_appl, p->cur_appl); 
    free(p->code); 
    free(p->name); 
} 

free(c); 
fclose(f); 
+0

你的代码使用strtok而不是strtok_r。在你的例子中也请使用strtok_r。 – fuz 2013-03-06 09:18:07

+0

@FUZxxl显然,它没有...:P – 2013-03-06 09:21:03

+0

要么我看不到,要么你修复速度不够快,无法创建新版本。 – fuz 2013-03-06 09:22:21