cha*_*hin 3 c arrays loops for-loop
首先,谢谢你的帮助!
我是C语言的新手(以及一般的编程),我正在尝试编写一个用户输入数据点的程序.然后将数据点保存在一个数组中,然后可以对它们进行操作.
我被卡住的地方:我希望用户能够输入(几乎)任意数量的点,然后使用各种"关键字"来表示数据输入的结束.在这种情况下,用户将键入"完成".
这是我到目前为止所拥有的:
#include <stdio.h>
#include <string.h>
int main(void) {
printf("\n Welcome! \n\n Please enter each data point. Enter 'done' when finished.\n\n");
double data[1048];
int i, count;
for (i = 1; ;i++) {
printf("Data[%i]: ", i);
scanf("%lf", &data[i]);
if (data[i] == 'done') {
break;
} else {
count++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我试过'返回1;' '打破;'.每次,程序运行良好,直到输入"关键字",此时我得到:
Data[8]: Data[9]: ... Data[1120]: Data[1Segmentation fault 11
Run Code Online (Sandbox Code Playgroud)
它唯一有效的时间是当用户输入特定数字(如-1或0)时它会中断.但这对用户来说并不是很有效,因为他们可能必须将这些数字作为数据点输入.
对不起,很长的帖子,但我感谢你的帮助!
您已经收到了许多问题的好答案,还有几种方法可以输入doubles和停止"done".由于您正在学习C,因此总是,总是(如果不清楚),请检查返回 scanf以验证您实际发生的转换次数.[1](这也提供了结束输入的方法"done"(或任何非双重输入导致scanf返回少于1)
正如评论中所指出的那样,数组在C 中为零.当你接受输入时,你会想要count用作你的数组索引,而不是i(在这种情况下,如果你在每次失败时退出读取 - 它不会问题,但你可以轻松地再次提示输入额外的输入,count只有在成功返回时增加scanf)回到你的问题.如果将读取循环设置为连续循环直到出现scanf故障,则可以使用临时变量来初始捕获输入值,并仅将值分配给数组并在成功时递增索引.例如(有一个常数MAXD = 1048)
for (;;) { /* loop until scanf input fails (with 'done') */
double tmp; /* block scope declarations are fine */
printf (" data[%4d]: ", count);
if (count < MAXD && scanf(" %lf", &tmp) == 1)
data[count++] = tmp;
else
break;
}
Run Code Online (Sandbox Code Playgroud)
(您甚至可以在循环上方移动提示的副本,并在达到if (....) {...}数组限制(MAXD)时消除提示后移动上面的提示- 这仍然是练习)
在上面的示例中,您有2个条件在存储值之前强制执行.(1)你限制值的个数用户可以存储MAXD,和(2)您只存储一个值,如果一个有效的转换double发生在scanf.如果其中一个条件失败,你就离开循环(如果你输入"done"一个双值,它就会出现).
将这些内容放在一起并在评论中添加一些额外的提示,您可以使用以下内容进行测试:
#include <stdio.h>
enum { MAXD = 1048 }; /* declare constants instead of using magic numbers */
int main (void) {
double data[MAXD] = {0}; /* in ISO C declarations come before code */
int i, count = 0; /* initializing variable saves debug time */
printf ("\n Welcome! \n\n Please enter each data point. "
"Enter 'done' when finished.\n\n");
for (;;) { /* loop until scanf input fails (with 'done') */
double tmp; /* block scope declarations are fine */
printf (" data[%4d]: ", count);
if (count < MAXD && scanf(" %lf", &tmp) == 1)
data[count++] = tmp;
else
break;
}
printf ("\n %d values entered:\n\n", count);
for (i = 0; i < count; i++)
printf (" data[%4d] : %.2lf\n", i, data[i]);
return 0; /* main() is type 'int' and returns a value */
}
Run Code Online (Sandbox Code Playgroud)
示例使用/输出
$ ./bin/scanfdoubles
Welcome!
Please enter each data point. Enter 'done' when finished.
data[ 0]: 1.1
data[ 1]: 1.2
data[ 2]: 1.3
data[ 3]: 1.4
data[ 4]: 1.5
data[ 5]: 1.6
data[ 6]: done
6 values entered:
data[ 0] : 1.10
data[ 1] : 1.20
data[ 2] : 1.30
data[ 3] : 1.40
data[ 4] : 1.50
data[ 5] : 1.60
Run Code Online (Sandbox Code Playgroud)
仔细看看,如果您有任何疑问,请告诉我.
脚注:
1.虽然您可以使用scanfC中的用户输入,但最好使用面向行的函数(如fgets),然后解析整行(例如sscanf).允许您同时(1)验证读取(例如返回fgets),然后(2)分别验证用户输入的值.读取和解析的这种分离具有许多优点.