【问题标题】:Write int structure data type to file in c在c中将int结构数据类型写入文件
【发布时间】:2014-03-09 16:33:27
【问题描述】:

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

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

在将数据写入文件之前,我的代码工作正常。 (这是代码的sn-p)

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);

提前谢谢你。

【问题讨论】:

  • My code works fine until the writing of the data to the file ... 那么会发生什么?
  • 输入的格式是什么?能举个例子吗?
  • @RobertHarvey 我的编译器给出了错误表达式:(str != NULL)
  • @TylerDurden 输入是 int 类型。 x 的值范围为 0-50,y 的值范围为 0-100。它是一种网格形式的表示。
  • @j_prog:编译器错误与您显示的代码无关。 str在哪里?

标签: c arrays struct int printf


【解决方案1】:

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

您的问题在于从stdin 输入的数据。首先,您阅读了scanf 的一堆坐标。 scanf 不是基于行的格式;它将换行符视为任何其他空格。

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

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

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

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

读取第一个数字后,输入标记位于数字之后,换行符之前。 scanf 在用"%d" 读取数字之前跳过空格,因此读入第二个数字,但同样,输入在换行之前停止。然后你用fgets 读了一行,然后读到下一个换行符,这没什么。真正的文件名会被下一个扫描函数读取,但是没有,所以被丢弃了。

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

(更糟糕的是:fgets,不像gets,在读取字符串之后保留换行符。你应该删除它以及可能的其他前导和尾随空格。否则你最终会得到一个文件名里面有一个换行符,这不好笑。)

无论如何,你怎么能解决这个问题?将您的scanf 格式从"%d" 更改为"%d ",并带有尾随空格。 “空格”对scanf 有一个含义:读取任意数量的空白。

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

据报道,您已通过在读取文件名之前调用 fflush(stdin) 来解决此问题。 fflush 在输入流上的行为取决于实现,标准不保证。如果它对你有用,就这样吧。

【讨论】:

  • 解释得很透彻!像这样格式化 fprintf 也不能解决这样的问题吗? fprintf(fp,"%d,%d",mg[loop].x,mg[loop].y);
  • 不,那是输出——完全是另外一回事。 fprintf 中的空格表示:写一个空格。我不喜欢从stdinscanf 交互式地阅读输入。例如,如果程序要求第一个值,用户可以写“2 3”,从而输入两个值,第二个值将从scanf 中读取,该scanf 在写入另一个promt 之后执行 - 在输入值之后.从现在开始,您的提示和数据将不同步。 (顺便说一句,解释很透彻,因为事情太复杂了。所有输入的东西都比你手头的实际问题复杂得多。)
猜你喜欢
  • 2018-07-08
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多