C 我的2D数组数据的函数声明和定义不起作用
我有一个包含12个月每日温度的数据文件。我希望该计划得到最低和最高温度为每个月使用的功能和打印在主功能。不知何故,我的函数声明和定义在我的教程之后不被接受。我试图在这里的帖子中修改程序:,我的程序变得更糟了。 需要帮助。 这是密码C 我的2D数组数据的函数声明和定义不起作用,c,C,我有一个包含12个月每日温度的数据文件。我希望该计划得到最低和最高温度为每个月使用的功能和打印在主功能。不知何故,我的函数声明和定义在我的教程之后不被接受。我试图在这里的帖子中修改程序:,我的程序变得更糟了。 需要帮助。 这是密码 #include <stdio.h> #include<stdlib.h> /* function declarations */ float max(float temp[][]); float min(float temp[][]);
#include <stdio.h>
#include<stdlib.h>
/* function declarations */
float max(float temp[][]);
float min(float temp[][]);
int main ()
{
float maxt, temp[31][12];
int i, j, year, month;
char value, buff[1000];
FILE *f1;
FILE *f2;
f1=fopen("temp_data.txt", "r");
f2=fopen("temp_out.txt", "w");
if (f1 == NULL)
{
printf("Can't open file\n",f1);
return 1;
}
if (f2 == NULL)
{
printf("Can't open file\n",f2);
return 1;
}
j=0;
while (fgets(buff, sizeof(buff), f1))
{
sscanf(buff, " %i %i", &year, &month);
for (i = 0; i <= 31; i++)
{
sscanf(buff, " %f", &temp[i][j]);
}
for(i = 0; i < 31; i++)
{
/* calling a function to get max value */
float maxt = max(temp);
float mint = min(temp);
printf( " %d Min=%5.1f Max=%5.1f\n", j, mint, maxt);
}
j=j+1
}
return 0;
}
/* function returning the max of 31 temperatures */
float max(float temp[][])
{
/* local variable declaration */
float maxt;
maxt=-99.;
int i,j;
for(i = 0; i < 31; i++)
{
if(temp[i][j] > maxt)
{
maxt=temp[i][j];
}
}
return maxt;
}
/* function returning the max of 31 temperatures */
float min(float temp[][])
{
/* local variable declaration */
float mint;
mint=99.;
int i,j;
for(i = 0; i < 31; i++)
{
if(temp[i][j] < mint)
{
mint=temp[i][j];
}
}
return mint;
}
函数声明中出错:数组类型的元素类型不完整
函数定义错误:forma参数1的类型不完整
函数“min”、“max”的两个少数参数和“min”、“max”的冲突类型
此处未声明的“j”也不在函数中
感谢您的帮助。根据第3版进行评论
有很多问题-我可能没有在下面的列表中记录和报告它们
您打开了一个输出文件,但从未使用过它。代码已删除。
打开固定名称的输入文件-不要打开。按照下面的代码从标准输入读取,或者在命令行上获取一个文件名并打开它。固定名称具有不必要的限制性。
您使用%i读取整数。如果你不是在读带前导零的十进制数,那就好了。但是,当sscanf看到08和%i时,它会将其读取为0,因为8不是有效的八进制数。
你没有系统地设计sscanf代码;这使得它无法阅读,也无法维护。
您的数据使用999.9表示“不存在的日期”。这是一种方法,但它使代码变得非常复杂。
你用你的阵型笨手笨脚的,我自己也是左撇子。您应该在31天内每月有12行,而不是在12个月内每天有31行。因此,代码中有temp[12][31]。
这样做意味着您可以将一个月的数据传递给聚合函数,而无需在函数中使用2D数组符号。
您的函数声明无法编译,因为您需要maxfloat temp[][12];在你的计划中。必须提供除第一个数组维度以外的所有数组维度的大小。
下面的替换代码通过将temp[month]传递给函数来获取一个月的数据。
可以简单地省略9月31日不存在的日子;2月30日和31日——由于数据中的年份是2012年,是闰年,所以2月在那一年有29天。当我在您添加测试数据之前为自己生成一些测试数据时,相同的代码在2月份有28个条目,9月、4月、6月和11月有30个条目,其余的31个条目。这降低了处理999.9的复杂性。
首先调用cnt,然后将该计数传递给其他聚合函数可能是明智的。它将允许您更容易地忽略虚拟值。您还可以验证虚拟值是否仅位于每行的末尾。
为了确定最低和最高温度,代码使用第一个温度并断言它不是虚拟温度作为初始猜测,然后对照该温度检查剩余温度。这通常是处理“初始值”问题的最佳方法。如果允许计数为零,则它将失败-代码应该但不会断言不允许计数为零。
为了利息起见,我加上平均值来计算平均值。
我添加了cnt,因为有必要对虚拟条目进行折扣。
这个问题变了形
我在历史记录中开始的代码版本包含以下语句:
j=0;
while (fgets(buff, 300, f1) != NULL)
{
sscanf(buff,"%i%i%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f",
&year,&month,&temp[0][j],&temp[1][j],&temp[2][j],&temp[3][j],&temp[4][j],&temp[5][j],&temp[6][j],&temp[7][j],&temp[8][j],&temp[9][j],&temp[10][j],
&temp[11][j],&temp[12][j],&temp[13][j],&temp[14][j],&temp[15][j],&temp[16][j],&temp[17][j],&temp[18][j],&temp[19][j],&temp[20][j],&temp[21][j],
&temp[22][j],&temp[23][j],&temp[24][j],&temp[25][j],&temp[26][j],&temp[27][j],&temp[28][j],&temp[29][j],&temp[30][j],&temp[31][j]);
for(i = 0; i < 31; i++)
{
/* calling a function to get max value */
float maxt = max(temp);
float mint = min(temp);
printf( " %d Min=%5.1f Max=%5.1f\n", j, mint, maxt);
}
j=j+1
}
根据您的示例数据,我得到的输出是:
2012-01: days = 31, min = 27.50, avg = 30.44, max = 32.70
2012-02: days = 29, min = 25.00, avg = 28.08, max = 33.00
2012-03: days = 31, min = 23.50, avg = 30.76, max = 33.60
2012-04: days = 30, min = 24.50, avg = 28.93, max = 32.60
2012-05: days = 31, min = 26.80, avg = 29.68, max = 31.60
2012-06: days = 30, min = 25.30, avg = 29.21, max = 32.20
2012-07: days = 31, min = 28.80, avg = 30.88, max = 32.60
2012-08: days = 31, min = 27.50, avg = 32.20, max = 34.80
2012-09: days = 30, min = 25.00, avg = 30.21, max = 34.00
2012-10: days = 31, min = 25.00, avg = 30.96, max = 33.10
2012-11: days = 30, min = 25.70, avg = 28.33, max = 32.70
2012-12: days = 31, min = 23.70, avg = 29.34, max = 32.60
这是我见过的最可怕的滥用sscanf和格式字符串的候选。所以你可以纠正我,我说我是从教程中得到的。fgets行应该是,而fgetsbuff、sizeofbuff、f1和sscanf行应该是类似SSCANFBUF、%I、&year、&month;对于i=0;关于如何在循环中使用sscanf的讨论,请参见。假设一个月的数据最多有29个条目,通常只有28个条目,那么你如何处理2月份的数据呢?您应该检查sscanf的返回值。注意:float maxfloat temp[]];浮点最小浮点温度[];不可接受C。只能省略数组的第一个维度;其他的必须以某种方式指定。可能是VLA的一部分,可能是固定大小。没有人指出OP的谬误,即试图用sscanf从字符数组中读取数据,就像用fscanf从文件*中读取数据一样。不幸的是,一个字符串并没有跟踪一个实际上是一个想法的读取位置,所以所有的sscanf都从字符串的开头读取。它们几乎都成功了,因为可以从有效的int字符串读取浮点,反之亦然。恕我直言,我发现你的解决方案是一次读取33个值。。。可憎的我要么要求C11与字符串文字连接,要么动态构建格式字符串。动态构建格式字符串的优势在于适应不同的月份长度,因为闰年!和m
on在运行时是已知的。-当然,否则这是一个很好的答案,投入了太多的工作…33立即就是OP在其代码中所拥有的内容-除了尝试将数组中不存在的元素传递给sscanf,而在没有格式字母的情况下,这是一个我以前忘记注意的细节-这是“OK”。至少答案中的代码根据sscanf的返回值检查合理性,而不是随意假设。不太明显的是,只发现了%i到%d的变化,因为8月的最小值是8,9月的最小值是9,这似乎不太可能。可以对代码进行其他更改;这不是一个完美的解决方案。就“太多太多的工作”部分达成一致。但我开始写它是因为这是一个编写一些数据生成脚本的机会,我一直想在某个时候开始编写这些脚本。它们并不完美,也与OP提供了样本数据后的答案不相关,但这一切都是一个借口,让我做了N年来一直想做的事情,其中N超过1的幅度相当大。@PeterA.Schneider:Hmm;你对循环中sscanf的评论是正确的——我只是没有注意到OP修改了问题中的代码。我现在已经确定了我的工作来源-谢谢你指出这个问题。我想如果我没有看到原始版本,我会编写一个不同的程序,在循环中正确使用sscanf。我不确定我是否有足够的精力来添加替代方案——我将把它作为OP的练习。至少代码使用了fgets和sscanf的组合;这对健全的运作至关重要。
2012-01: days = 31, min = 27.50, avg = 30.44, max = 32.70
2012-02: days = 29, min = 25.00, avg = 28.08, max = 33.00
2012-03: days = 31, min = 23.50, avg = 30.76, max = 33.60
2012-04: days = 30, min = 24.50, avg = 28.93, max = 32.60
2012-05: days = 31, min = 26.80, avg = 29.68, max = 31.60
2012-06: days = 30, min = 25.30, avg = 29.21, max = 32.20
2012-07: days = 31, min = 28.80, avg = 30.88, max = 32.60
2012-08: days = 31, min = 27.50, avg = 32.20, max = 34.80
2012-09: days = 30, min = 25.00, avg = 30.21, max = 34.00
2012-10: days = 31, min = 25.00, avg = 30.96, max = 33.10
2012-11: days = 30, min = 25.70, avg = 28.33, max = 32.70
2012-12: days = 31, min = 23.70, avg = 29.34, max = 32.60