在c中将int结构数据类型写入文件

时间:2014-03-09 16:33:28

标签: c arrays struct int printf

我的程序的一些背景知识。我要求用户输入两种不同颜色的水晶坐标。这将保存在一个结构中,然后写入文件,稍后由程序读回(函数尚未写入)。

我看过论坛和博客,但我似乎只找到与字符数组相关的结果,而我使用的是int数组。

我的代码正常工作,直到将数据写入文件。 (这是代码片段)

char fname[20];
FILE *fp;
int loop;
struct coord{
int x;
int y;
    };

for(loop=0;loop<3;loop++){
printf("Enter MAGENTA X coordinate: \n");
    scanf("%2d",&mg[loop].x);
printf("Enter MAGENTA Y coordinate: \n");
    scanf("%2d",&mg[loop].y);
    printf("\n\n");
}

for(loop=0;loop<3;loop++){
printf("Enter YELLOW X coordinate: \n");
    scanf("%2d",&ylw[loop].x);
printf("Enter YELLOW Y coordinate: \n");
    scanf("%2d",&ylw[loop].y);
    printf("\n\n");
}

clrscr();

printf("\nDetail entered:");
printf("\n\n\tMagenta\t\tYellow\n");
for(loop=0;loop<3;loop++){
    printf("\tx %d,%d y\tx %d,%d y\n",mg[loop].x,mg[loop].y,ylw[loop].x,mg[loop].y);
}

printf("\n\nPlease save your data. Enter file name: ");
gets(fname);
fp=fopen(fname,"w");

for(loop=0;loop<3;loop++){
    fprintf(fp,"%d,%d ",mg[loop].x,mg[loop].y);
    fprintf(fp,"%d,%d ",ylw[loop].x,ylw[loop].y);
}

fclose(fp);

提前谢谢。

1 个答案:

答案 0 :(得分:0)

将数据写入文件的方式没有任何问题(除了您应该检查fopen的返回值之外。)

您的问题来自stdin的数据输入。首先,您使用scanf读取一堆坐标。 scanf不是基于行的格式;它像任何其他白色空间一样对待新行字符。

然后你使用gets,你真的不应该 - 使用fgets代替,因为它允许你指定一个最大缓冲区大小,这样你就不会溢出20的缓冲区。 / p>

好吧,假设您使用fgets,这是一种基于行的格式。混合scanffgets时必须小心,因为它们的工作方式不同。此外,控制台的输入通常会被缓冲,直到下一个换行符全部刷新为止,这会在屏幕上看到的内容与程序处理输入之间产生差异。

假设您使用scanf读取两个数字,然后使用fgets读取文件名。您的输入如下所示:

1  2  \n  5  1  \n  d  a  t  a  .  t  x  t
a  a  b   b  b  c

读取第一个数字后,输入标记位于换行符之前的数字之后。在使用scanf读取numbners之前,"%d"会跳过空格,因此读入第二个数字,但同样,输入在换行符之前停止。然后你读了fgets的一行,并读到下一行的所有内容,这一切都没有。实际的文件名将由下一个扫描函数读取,但没有,所以它被丢弃。

(那就是你的str != NULL is coming from: it's an assertion that has failed within fopen`。这是编译器所做的事情。当你运行程序时,它已经被编译了。运行时库对编译时无法知道的条件进行错误检查。)

(更糟糕的是:fgets,与gets不同,在读取字符串后保留换行符。你应该删除那个以及可能的其他前导和尾随空格。否则你最终会文件名中包含换行符,这并不好笑。)

无论如何,你怎么能解决这个问题?使用尾随空格将scanf格式从"%d"更改为"%d "。 “空间”具有scanf的含义:读取任何数量的空白区域。

或者,您可以坚持scanf并使用scanf("%19s ", filename)阅读您的电子名称。这样做的好处是可以读取一个没有任何空格的字符串。

据报道,您已经通过在读取文件名之前调用fflush(stdin)来解决此问题。 fflush对输入流的行为取决于实现,并且不受标准保证。如果它适合你,请保留它。