我正在写一个程序,应该是序列化/反序列化CSV到BIN/BIN到CSV在C。目前,我正在第三天与反序列化斗争,因为我尝试了所有我能做的,我决定在这里问。
我做序列化的方式如下:
void serialize(FILE* input_file,FILE* output_file)
{
char buffer[MAX_LINE_LENGTH];
struct order
{
char* row_id;
char* order_id;
char* order_date;
char* customer_id;
char* city;
char* state;
char* postal_code;
char* region;
char* product_id;
char* category;
char* sub_category;
char* price;
} ;
struct order order_buffer = {0};
fgets(buffer,MAX_LINE_LENGTH, input_file);
while(fgets(buffer, MAX_LINE_LENGTH, input_file) != NULL)
{
char* token = NULL;
token = strtok(buffer, ",");
order_buffer.row_id = token;
token = strtok(NULL, ",");
order_buffer.order_id = token;
token = strtok(NULL, ",");
order_buffer.order_date = token;
token = strtok(NULL, ",");
order_buffer.customer_id = token;
token = strtok(NULL, ",");
order_buffer.city = token;
token = strtok(NULL, ",");
order_buffer.state = token;
token = strtok(NULL, ",");
order_buffer.postal_code = token;
token = strtok(NULL, ",");
order_buffer.region = token;
token = strtok(NULL, ",");
order_buffer.product_id = token;
token = strtok(NULL, ",");
order_buffer.category = token;
token = strtok(NULL, ",");
order_buffer.sub_category = token;
token = strtok(NULL, ",");
order_buffer.price = token;
fwrite(&order_buffer, sizeof(order_buffer), 1, output_file);
}
}
这段代码逐行获取CSV文件并在逗号上标记它。
之后,它将其存储到一个结构体中(本次迭代中的所有char数组,尽管其中一些是int)
到这里为止一切都很好,我能够序列化CSV文件并将其大小从1.2MB减少到大约470 kb。
但是,我不能反序列化它。
我尝试了几种不同的方法,最后我决定fscanf是最好的,下面是代码:
void deserialize(FILE* input_file, FILE* output_file)
{
char buffer[MAX_LINE_LENGTH];
struct order
{
char* row_id;
char* order_id;
char* order_date;
char* customer_id;
char* city;
char* state;
char* postal_code;
char* region;
char* product_id;
char* category;
char* sub_category;
char* price;
} ;
struct order order_buffer = {0};
char* line[MAX_LINE_LENGTH];
fscanf(input_file, "%s%s%s%s%s%s%s%s%s%s%s%s",
order_buffer.row_id,
order_buffer.order_id,
order_buffer.order_date,
order_buffer.customer_id,
order_buffer.city,
order_buffer.state,
order_buffer.postal_code,
order_buffer.region,
order_buffer.product_id,
order_buffer.category,
order_buffer.sub_category,
order_buffer.price);
printf("%s", order_buffer.order_id);
printf("%s", order_buffer.row_id);
}
该函数可以创建一个新的csv文件,但不向其中写入任何内容,也不向结构体分配任何值。
我猜这和char数组未初始化有关,但除此之外,我完全迷路了。
我做错了什么?
2条答案
按热度按时间bq3bfh9z1#
您正在初始化一个订单结构,其中指针指向一些文本字符串数据....
然后将指针写入磁盘。您没有编写它们指向的文本字符串。
如果您要将CSV数据解析为有意义的内容,即将
state
的文本字符串解析为一个枚举:然后,在fwrite/fread上抛出它应该没问题,不需要额外的工作。
如果像'product_id'这样的东西很好地Map为一个整数,那么在结构中使用整数!
如果你需要一个实际的文本字符串作为数据结构的一部分,你要么需要使用一个固定大小的char数组,要么更聪明(例如fwrite字符串大小,然后fwrite实际字符串数据)。
对于像'price'这样的东西,要么使用十进制类型,要么以便士/美分的倍数存储,并使用整数。
然后,当你读回它,所有的数据,你期望将在那里,例如。
但是,如果您想将所有内容保存为文本字符串,只需使用原始CSV文本文件作为存储....
guicsvcw2#
有两个逻辑错误。
输出为
fwrite(&order_buffer, sizeof(order_buffer), 1, output_file);
。它只会将
char *
指针写入文件,而不是它们指向的内存。不会是你想要的。另一个错误:
%s
将停止匹配,直到' '
,'\t'
或'\n'
。您使用
fwrite()
编写内容,它不会添加空白字符。然后第一个
%s
将匹配整个字符串,直到EOF
被调用时。另一个潜在错误是混合
fwrite()
和fscanf()
时字节对齐。fread()
通常与fwrite()
一起使用。并且fscanf()
与fprintf()
一起使用。如果使用
fscanf()
,最好在fprintf()
中添加空格或宽度。例如: