请问更多代码。
int serialize_students(const Student *studArray, const int arrLength)
{
FILE *ptr_file;
int i=0;
ptr_file =fopen("output.txt", "w");
if (!ptr_file)
return -1;
for (i=0; i<arrLength; i++)
{
fprintf(ptr_file,"%d\n", studArray[i].id);
fprintf(ptr_file,"%s\n", studArray[i].name);
fprintf(ptr_file,"%d\n", studArray[i].gender);
}
fclose(ptr_file);
return 0;
}
int deserialize_students(Student *dest, const int destCapacityMax)
{
FILE *ptr_file;
int i=0;
ptr_file =fopen("output.txt","r");
if (!ptr_file)
return -1;
if(destCapacityMax==0)
return -2;
while (!feof (ptr_file))
{
fscanf (ptr_file, "%d", &dest[i].id);
fscanf (ptr_file, "%s", dest[i].name);
fscanf (ptr_file, "%d", &dest[i].gender);
i++;
if(i==destCapacityMax)
return 0;
}
fclose(ptr_file);
return 0;
}
void print_student(Student student)
{
printf("id: %d\n", student.id);
printf("name: %s\n", student.name);
printf("gender: %d\n", student.gender);
}
void print_students(const Student *studArray, const int arrLength)
{
int i = 0;
for(i =0; i<5;i++)
{
print_student(studArray[i]);
}
}
主
typedef struct student
{
int id;
char name[100];
int gender;
}Student;
int main()
{
int i = 0;
Student dest[5];
Student students[5];
memset(dest,0,sizeof(dest));
memset(students,0,sizeof(students));
/* Initialize students */
/*for(i = 0; i<5; i++)
{
students[i].id = i;
strcpy(students[i].name,arr[i]);
students[i].gender = MALE;
}*/
/*Serialize*/
serialize_students(students,5);
/* Reconstruct student array from file */
deserialize_students(dest, 5);
/* Print reconstructed array of students */
print_students(dest,5);
return 0;
}
我的问题是:看看数据是如何写入文件的,看看它是如何在控制台上打印的?他们为什么不同?为什么只有名字的前三个值显示为0?但其他两个空?
这就是文件的样子
这是控制台输出:
答案 0 :(得分:0)
简单地回答你的问题&#34; fscanf是否会返回ASCII&#39; 0&#39;当读取空字符串?&#34;,否,它不返回ASCII零。它返回成功读取的字段数(或者在读取错误或文件结束时的EOF)。由于它没有从空字符串中读取任何字段,因此返回整数0。
对于您的其他问题部分,我需要打印功能。但可能,您在阅读字段后忘记跳过终止空格(\ n)。
编辑:有趣....我将你的源代码复制到我的VC2008中,它运行良好。我没有在格式规范中添加空格(可以跳过换行符和其他空格),而fscanf
只是忽略了换行符。我查看了Microsoft文档,它没有说明任何内容 - 它不应该跳过新行,但确实如此。我在每个格式说明符之前和之后都添加了一个空格来忽略仍在缓冲区中的空格并且没有任何区别。我抛弃了输出,每条线路都有整齐的0x0D, 0x0A
CR / LF对。任何建议?或者这是微软的异常吗?
编辑:用户Freenode-Boston Seb引用IEEE编写的scanf手册&#34; 输入空白字符(由isspace指定)将被跳过,除非转换规范包括[,c,C或n转换说明符。&#34;这就在这里,所以根据这本手册你的代码很好。
答案 1 :(得分:0)
除非转换规范包含
[
,c
,C
或n
转换说明符,否则应跳过输入空白字符(由isspace指定)
换句话说,在%d
和%s
读取之前,将尽可能多地读取和丢弃空格。
重要的是要意识到这些不会读取空字段!您感知的空字段将被丢弃,因为它们是空白流的一部分。
scanf
和fscanf
并非真正适用于逐行输入。它们更适合逐字段输入,%s
表示由空格分隔的字(并且不为空)和{{ 1}}表示一个十进制数字字符序列,可能带有前导符号(并且不为空)。
这将解释为什么您会看到包含%d
,0
,1
的字符串字段或您希望归入42
变量的任何其他十进制数字序列。< / p>
也许,如果您在使用它们之前花费更多时间阅读和理解函数手册,那么您可能会遇到这种特殊问题,与猜测函数的使用方式有关,将来会减少... < / p>
P.S。不要忘记检查返回值。