当用户在c中输入输入时停止for循环

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)时它会中断.但这对用户来说并不是很有效,因为他们可能必须将这些数字作为数据点输入.

对不起,很长的帖子,但我感谢你的帮助!

Dav*_*ica 5

您已经收到了许多问题的好答案,还有几种方法可以输入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)分别验证用户输入的值.读取和解析的这种分离具有许多优点.