2013-03-06 117 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