【发布时间】:2017-06-28 06:32:35
【问题描述】:
我正在编写将文本文件转换为二进制文件的代码。它不返回任何错误并且运行良好,除了在这个特定示例中它不打印名字的事实。我的输入文件包含john doe 1 4.0。预期的输出是johndoe@▒,但我的输出是doe@▒。我尝试使用 fseek 来移动偏移量。我尝试以不同的方式关闭文件。我尝试重命名我的变量并更改 if 语句。
我不完全确定,但我觉得错误可能来自循环。如果我交换名字和姓氏,会发生同样的事情但相反,这意味着我的代码忽略了首先使用 fwrite 读取的任何内容。我的代码有什么问题导致这种情况发生?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void textToBinary(char *inputFile, char *outputFile){
FILE *ifp, *ofp;
char firstName[256], lastName[256];
int sID;
float gpa;
unsigned char firstNameLen = strlen(firstName);
unsigned char lastNameLen = strlen(lastName);
if(((ifp = fopen(inputFile, "r")) != NULL)&&((ofp = fopen(outputFile, "w")) != NULL)){
while((fscanf(ifp, "%s %s %d %f\n", firstName, lastName, &sID, &gpa)) != EOF){
fwrite(&firstNameLen, sizeof(firstNameLen), 1, ofp);
fwrite(firstName, sizeof(char), firstNameLen, ofp);
fwrite(&lastNameLen, sizeof(lastNameLen), 1, ofp);
fwrite(lastName, sizeof(char), lastNameLen, ofp);
fwrite(&sID, sizeof(int), 1, ofp);
fwrite(&gpa, sizeof(float), 1, ofp);
}
fclose(ifp);
fclose(ofp);
}else{
fprintf(stderr, "Couldn't open: %s\n", ifp);
}
}
【问题讨论】:
-
您正在计算垃圾缓冲区值上的
firstNameLen和lastNameLen。这些属于循环内部。 -
您的
fscanf()支票应该是== 4而不是!= EOF。您可能会得到数字 0、1、2 或 3 以及 EOF,它们都表示存在问题。 -
char firstName[256], ... unsigned char firstNameLen = strlen(firstName);是 UB -
从风格上讲,您最好将打开的文件拆分为更多行。使用
if ((ifp = fopen(inputFile, "r")) == NULL) { …report error opening inputFIle… } else if ((ofp = fopen(outputFile, "w")) == NULL) { fclose(ifp); …report error opening outputFile… } else { …while loop and fcloses… }。这为您提供更准确的错误报告,并且在适当间隔时更具可读性。请注意,printf("Couldn't open: %s\n", ifp);将报告文件名为(null),如果你很幸运,或者如果输入文件无法打开则崩溃,如果输出文件无法打开,则会出现乱码。 -
感谢@Gene 工作。我明白现在发生了什么
标签: c file while-loop fwrite scanf