我需要将以下格式的文本文件转换为二进制文件:
第一行包含清单中的产品数量,以下行包含:
产品名称'\t'
产品价格'\t'
数量'\n'
(列之间可以有多个\ t)
对于每个产品,二进制输出文件将包含一个表示产品名称长度的int,包含产品名称的字符,一个表示价格的int和一个表示数量的int。
示例输入文件:
Asus Zenbook 1000 10
iPhone 5 750 22
Playstation 4 1000 0
我已经编写了以下代码,我明白我应该在纯文本中看到字符串,而整数将显示为乱码(二进制):
int convertTextToBinary(char *fileName)
{
FILE *pText, *pBinary;
int size, i;
char *currProdName;
int currProdNameLen, currQuantity, currPrice;
if (checkFileExists(fileName) == FALSE)
{
printf("- Given file does not exists!\n");
return ERROR;
}
else
pText = fopen(fileName, "r");
// get the number of products in the inventory
fscanf(pText, "%d", &size);
#ifdef DBG
printf("##DBG Successfuly read &size = %d DBG##\n", size);
#endif
pBinary = fopen(strcat(fileName, ".bin"), "wb");
fwrite(&size, sizeof(int), 1, pBinary);
#ifdef DBG
printf("##DBG Successfuly wrote &size = %d DBG##\n", size);
#endif
for (i = 0; i < size; i++)
{
// get product name and name length
currProdNameLen = getProdName(pText, &currProdName);
#ifdef DBG
printf("##DBG %d Successfuly read &currProdName = %s DBG##\n", i+1, currProdName);
printf("##DBG %d Successfuly read &currProdNameLen = %d DBG##\n", i+1, currProdNameLen);
#endif
// get product price
fscanf(pText, "%d", &currPrice);
printf("##DBG %d Successfuly read &currPrice = %d DBG##\n", i+1, currPrice);
// get product quantity
fscanf(pText, "%d", &currQuantity);
printf("##DBG %d Successfuly read &currQuantity = %d DBG##\n", i+1, currQuantity);
// write data to binary file
fwrite(&currProdNameLen , sizeof(int), 1, pBinary);
fwrite(&currProdName, sizeof(char), currProdNameLen, pBinary);
fwrite(&currPrice, sizeof(int), 1, pBinary);
fwrite(&currQuantity, sizeof(int), 1, pBinary);
free(currProdName);
}
fclose(pText);
fclose(pBinary);
return 1;
}
/* This function checks if a file in a given path exists or not by using fopen with "read" argument */
BOOL checkFileExists(char *fileName)
{
FILE *fp;
fp = fopen(fileName, "r");
// file does not exists
if (fp == NULL)
return FALSE;
// file does exists
else
{
fclose(fp);
return TRUE;
}
}
int getProdName(FILE *fp, char **prodName)
{
int nameLen = 0, offset;
// count the length of the product name
while (fgetc(fp) != '\t')
nameLen++;
// allcoate memory for the product name
*prodName = (char*)malloc(sizeof(char)*nameLen);
//checkalloc(&prodName);
// get the cursor back to the original position
offset = -1 * nameLen;
fseek(fp, offset, SEEK_CUR);
// copy product name from text to string
fgets(*prodName, nameLen, fp);
return strlen(*prodName);
}
但是地狱,我的输出文件看起来像这样:
¨ ּּּּּט ¨ ּּּ¯ ¨ ּּּּּּּּ ּּּ«
¨
没有明文。我已经尝试将fopen参数从“wb”改为“w”但我仍然得到乱码文件。我做错了什么?
答案 0 :(得分:1)
在这里你写指针和额外的垃圾,而不是它指向的字符串:
fwrite(&currProdName, sizeof(char), currProdNameLen, pBinary);
您应该使用:
fwrite(currProdName, sizeof(char), currProdNameLen, pBinary);
在您的版本中,您将指针传递给指针,但您想要传递指针本身。
BTW:在你的函数getProdName()
中,你应该添加一个额外的字符,因为你正在分配精确的字符串长度,但最后没有0
字节的空间。这也可能导致问题。另外fgets
读取少一个字符。查看fgets
的手册页。您也可以使用fgets
,而不是使用fread
,因为您无论如何都知道长度。无需额外解析。
<强>更新强>
改变这个:
fscanf(pText, "%d", &currQuantity);
到
fscanf(pText, "%d\n", &currQuantity);