2016-12-07 39 views
1

如何讀取二進制文件並將其值分配給結構?每個結構及其內容都將被寫入一個csv文件。將文件的字節讀入結構中

我有這個data file,這是一個struct product條目列表。

下面是一個.h文件的Product結構:

struct product { 
    char code[15]; 
    char name[50]; 
    short int quantity; 
    double price; 
} 

typedef struct product *Product; 

這裏是我怎樣,我想讀每一行到產品結構,並將其寫入到CSV文件:

File *fp; 
File *outFile; 
fp = fopen("products.dat", "rb"); 
outFile = fopen("allproducts.csv", "w"); 
Product p; 

while (fread(p, sizeof(Product), 1, fp) == 1) { 
    fwrite(p->code, sizeof(p->code), 1, outFile); 
} 

我不認爲我正在讀取文件,因爲當我嘗試寫入文件時,我所得到的只是csv文件中的一個框中的問號。

+0

使用'fprintf'而不是'fwrite'。 – BLUEPIXY

+0

@BLUEPIXY謝謝你的建議。但是,我仍然在文件 – Jasmine

+0

中得到相同的錯誤輸出。'''p'是指針類型。你沒有分配它。和'sizeof(Product)'是錯誤的。 – BLUEPIXY

回答

0

如果數據文件的作者沒有注意它所寫的struct的大小,讀者很難理解它。我玩了一會兒,發現需要進行一些小調整才能在我的機器和操作系統上獲得正確的結果

#include <stdio.h> 
#include <stdlib.h> 

#define ADJUSTMENT 4 

struct product { 
    char code[15]; 
    char name[50]; 
    short int quantity; 
    double price; 
}; 

int main(void) 
{ 
    FILE *fp; 
    //FILE *outFile; 
    struct product p; 

    fp = fopen("products.dat", "rb"); 
    if (fp == NULL) { 
    fprintf(stderr, "fopen failed\n"); 
    exit(EXIT_FAILURE); 
    } 
    //outFile = fopen("allproducts.csv", "w"); 

    while (fread(&p, sizeof(p) - ADJUSTMENT, 1, fp) == 1) { 
    printf("CODE: %s\n", p.code); 
    } 
    exit(EXIT_SUCCESS); 
} 

這是一個衆所周知的問題,寫二進制數據,簡單的嘗試,它是不便攜,我敢肯定,我的調整值不適合你。你需要找到一種方法來使其具有可移植性。

+0

爲什麼你需要調整? – 2016-12-07 09:20:09

+0

@Rhymoid編譯器可能已經填充了它以獲得更好的字節對齊,可能使用了4字節的「int」而不是2字節的「short」等。 – deamentiaemundi

0

我認爲你的下面的代碼需要修改。

你的原始編碼:

File *fp; 
File *outFile; 
fp = fopen("products.dat", "rb"); 
outFile = fopen("allproducts.csv", "w"); 
Product p; 

while (fread(p, sizeof(Product), 1, fp) == 1) { 
    fwrite(p->code, sizeof(p->code), 1, outFile); 
} 

修改代碼:

File *fp; 
File *outFile; 
fp = fopen("products.dat", "rb"); 
outFile = fopen("allproducts.csv", "w"); 
Product p = malloc(sizeof(struct product)); 

while (fread(p, sizeof(struct product), 1, fp) == 1) { 
    fwrite(p->code, sizeof(p->code), 1, outFile); 
} 

的問題是:

  1. p是一個指向struct,因爲它是Product類型是一個指針的要結構化,你需要爲它分配內存,然後才能使用它
  2. fread中,您傳遞的是sizeof(Product),它基本上傳遞指針的大小,而您想要讀取結構乘積的大小。

我沒有糾正的其他問題是檢查fopen,malloc等我將它留給你的返回值。 :)

0

隱藏typedefs後面的指針很容易出錯,並導致代碼混淆。

  • p被定義爲一個指向struct product,但沒有被初始化:其值傳遞給fread作爲目的地調用未定義的行爲。

  • sizeof(Product)是指針的大小,而不是結構的大小。

不要定義Product爲指針,如果你可以把它的typedef結構,或者不使用的typedef,如果你不能:

struct product { 
    char code[15]; 
    char name[50]; 
    short int quantity; 
    double price; 
}; 

typedef struct product Product; 

調整代碼和寫入字符串到csv文件,而不是字符的完整陣列:

File *fp; 
File *outFile; 
fp = fopen("products.dat", "rb"); 
outFile = fopen("allproducts.csv", "w"); 
struct product prod; 

while (fread(&prod, sizeof(prod), 1, fp) == 1) { 
    fprintf(outFile, "%s\n", prod.code); 
} 

注意,如果產品代碼包含嵌入的空格,這將是不正確的,,"或換行符。