我刚刚被介绍给C,我被分配编写了一个程序,可以模仿杂货店的自助退房行。这涉及我必须根据用户输入填充杂货项目的价格数组,并将它们添加并复制到文件中。
填充整数数组的最简单方法是使用for循环。但是对于float类型的数组会有什么不同吗?
它看起来像这样吗?或者这是不正确的?int size, i;
float items[size];
printf("How many items are you checking out today?");
scanf("%d", &size);
for(i=0;i<size;i++){
printf("Enter the price of an item\n");
scanf("%f", items[i]);
}
我是这个网站的新手,所以提前感谢
答案 0 :(得分:3)
我建议在声明变量时始终初始化变量,以防止出现“垃圾”值。另外,我真的不建议预先声明你的循环计数器。你在许多旧代码中看到它(由于编译器的限制,它曾经是必需的),但现在我只是认为它是代码噪声。它看起来像这样:
GMP
此外,您的代码存在很大问题。您正在使用所谓的可变大小数组,它们是not a good idea。您通常希望在编译时声明数组大小,或使用for (int i = 0; i < size; i++) {
// stuff
}
为数组动态分配空间。
回到初始化,这就是你如何在声明中设置堆栈分配数组中的每个元素:
malloc
如果您动态分配数组,我建议使用#define SIZE 4
int main(void)
{
float items[SIZE] = { 0 };
}
或calloc
将数组元素设置为默认值,原因相同。
要回答关于填充数组的问题,是的,关于如何实际执行此操作没有任何区别。在两种情况下,for循环都可以正常工作。请记住检查memset
的返回值。
答案 1 :(得分:2)
正如已经正确指出的那样,在float items[size];
被有效初始化为正整数值之前,您无法声明size
。由于您尝试访问未初始化的值,因此在items
之前声明size
包含值的尝试会调用未定义的行为。 (代码的有效操作已经结束,它可以执行任何操作,从显示正确运行到StackOverflow或SegFaulting)
无论何时进行用户输入,你都必须考虑输入缓冲区中保留的每个字符(stdin
此处)。由于scanf
处理输入或匹配失败的方式,在使用scanf
(或系列)输入时尤其如此。当两者都发生时,不再读取其他字符,并且任何有问题的字符在输入缓冲区中都未被读取 - 只是等待您在下一次尝试读取时再次咬你(如果你通常会导致无限循环)正在循环中输入)
(这是面向行的函数(如fgets
建议用于输入用户输入的主要原因之一)
scanf
。这意味着您负责每次检查scanf
的返回。您必须处理三个条件
(return == EOF)
用户通过按 Ctrl + d (或在Windows Ctrl + z 上生成手动EOF
来取消输入,但请参阅CTRL+Z does not generate EOF in Windows 10); (return == expected No. of conversions)
表示读取成功 - 然后由您来检查输入是否满足任何其他条件(例如正整数,正浮点等);和'\n'
或EOF
丢弃任何剩余的无关字符为止。如果您的工作正常,您可以根据需要成功使用scanf
。
接下来,一般警告不要使用浮点货币(当你因为舍入错误而开始赔钱时,人们会变得非常生气)虽然这对你的示例程序来说很好 - 只是理解,在实际货币处理程序中,您可以将货币作为无符号值乘以100
(或任何需要的值)来确保所有金额都能准确表示。
将scanf
要求放在一起,您可以安全地执行以下操作:
#include <stdio.h>
/* function to empty extraneous characters from stdin
* (like the '\n' generated by pressing [Enter])
*/
void empty_stdin()
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int size = 0, i;
float total = 0.0;
for (;;) { /* loop continually until valid size entered */
int rtn;
printf ("How many items are you checking out today?: ");
rtn = scanf ("%d", &size);
if (rtn == EOF) { /* handle EOF */
fprintf (stderr, "(user canceled input)\n");
return 1;
}
else if (rtn == 1 && size > 0) { /* valid int received */
empty_stdin();
break;
} /* otherwise, handle error */
fprintf (stderr, "error: invalid input.\n\n");
empty_stdin (); /* remove any chars from stdin up to '\n' */
}
float items[size]; /* declare VLA of size floats */
for (i = 0; i < size; i++) {
items[i] = 0.0; /* initialize each (or memset VLA) */
for (;;) { /* loop continually until valid item price entered */
int rtn;
printf (" price of item[%2d]: ", i + 1); /* prompt for price */
rtn = scanf ("%f", &items[i]);
if (rtn == EOF) { /* handle EOF */
fprintf (stderr, "(user canceled input)\n");
return 1;
}
else if (rtn == 1 && items[i] > 0) { /* valid price received */
empty_stdin();
break;
} /* otherwise, handle error */
fprintf (stderr, "error: invalid input.\n\n");
empty_stdin (); /* remove any chars from stdin up to '\n' */
}
total += items[i];
}
printf ("\ntotal (%d items): $%.2f\n", size, total);
}
示例使用/输出
(在输入时出现故意错误)
$ ./bin/checkout
How many items are you checking out today?: what?
error: invalid input.
How many items are you checking out today?: 4
price of item[ 1]: free?
error: invalid input.
price of item[ 1]: 1.25
price of item[ 2]: 3.50
price of item[ 3]: discount?
error: invalid input.
price of item[ 3]: 2.25
price of item[ 4]: 3
total (4 items): $10.00
仔细看看,如果您有其他问题,请告诉我。
答案 2 :(得分:0)
在使用方面,数组的使用没有区别。但是您的代码中几乎不需要进行任何更改。
#define MAX_SIZE (10)
int size=0, i=0; //It is always better to initialize the variables.
float items[MAX_SIZE] = {0.0f}; //Automatically the entire array will be initialized to zero.
printf("How many items are you checking out today?");
scanf("%d", &size);
if(size > MAX_SIZE)
size = MAX_SIZE;
for(i=0;i<size;i++){
printf("Enter the price of an item\n");
scanf("%f", &items[i]); //You need to pass address of variable to scanf
}
还有其他方法可以实现代码来处理数组大小。这是其中一种方式。