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

首先,谢谢你的帮助!

我是C语言的新手(以及一般的编程),我正在尝试编写一个用户输入数据点的程序。 然后将数据点保存在一个数组中,然后可以对它们进行操作。

我被卡住的地方:我希望用户能够输入(几乎)任意数量的点,然后使用各种“关键字”来表示数据输入的结束。 在这种情况下,用户将键入“完成”。

这是我到目前为止所拥有的:

#include  #include  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++; } } } 

我试过’返回1;’ ‘打破;’。 每次,程序都能正常运行,直到输入“关键字”,此时我得到:

 Data[8]: Data[9]: ... Data[1120]: Data[1Segmentation fault 11 

它唯一有效的时间是当用户输入特定数字(如-1或0)时它会中断。 但这对用户来说并不是很有效,因为他们可能必须将这些数字作为数据点输入。

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

你已经收到了很多关于你的问题的好答案,还有几种方法可以输入doubles并停止"done" 。 由于您正在学习C,因此总是, 总是 (如果不清楚), 请检查 scanf 的返回以validation您实际发生的转换次数。 [1] (这也提供了结束"done"输入的方法(或任何非双重输入导致scanf返回小于1

正如评论中所指出的那样,数组在C中为零 。当你接受输入时,你会想要使用count作为你的数组索引,而不是i (在这种情况下,如果你在每次失败时退出读取 – 它不会没关系,但只有在从scanf成功返回时,您才可以轻松地再次提示输入额外的输入和增量count 。)回到您的问题。 如果设置读取循环以持续循环直到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; } 

(您甚至可以在循环上方移动提示的副本,并在if (....) {...}之后移动上面的一个,以在达到数组限制( MAXD )时消除提示 - 这是左边的作为练习)

在上面的示例中,您有2个条件在存储值之前强制执行。 (1)您将用户可以存储的值的数量限制为MAXD ,(2)如果在scanf进行有效的double scanf转换,则只存储一个值。 如果其中一个条件失败,你就离开循环(如果你输入"done"作为一个双值,它就会)。

将这些部分放在一起并在评论中添加一些额外的提示,您可以使用以下内容进行测试:

 #include  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 */ } 

示例使用/输出

 $ ./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 

仔细看看,如果您有任何疑问,请告诉我。

脚注:

1.虽然您可以使用scanf在C中获取用户输入,但最好使用面向行的函数(如fgets )然后解析整行(例如sscanf )。 允许您同时(1)validation读取(例如fgets的返回),然后(2)分别validation用户输入的值。 读取和解析的这种分离有许多优点。

数据[]的任何元素都不会被“完成”(它们是浮点数)。 如果你想直接scanf(),你需要选择一个结束序列的double值(通常为零或-1或其他)。 如果这不起作用,您可以使用以下内容:

  1. 使用fgets()来拉取字符串,然后使用strncmp()来检查终止值,使用sscanf()来拉出double,或者:
  2. 让用户使用Ctrl-D终止并检查EOF的扫描值。

哦,严格来说,你有一个条目的上限。 你应该检查我,以确保你不超过这个。 永远不要假设您的输入不会超出边界。 静态分配变量上的sizeof()或一些#defined宏来跟踪它。

  • 您的data类型为double 。 它无法扫描文字“完成”。

而是使用EOF检查输入结束。

 while(scanf("%lf",&data[i]) != EOF) { ... } 

其他方式:

 while(scanf("%lf",&data[i]) == 1) { ... } 
  • 另一件事,初始化计数为零,即count = 0;

底线:不要使用scanf

使用类似的东西

 char inputline[100]; i = 0; while(fgets(inputline, sizeof(inputline), stdin) != NULL) { if(strncmp(inputline, "done", 4) == 0) break; data[i++] = atof(inputline); } 

即使所有输入都是您期望的数字, scanf也很难使用。 如果输入可能是数字或单词“done”,则scanf将永远不会起作用。 但是,阅读一行文本(如此处)通常更容易,也更灵活。

PS您还必须担心用户输入超过1048个号码的可能性。

对于您的任务,收集输入的循环不仅应控制关键字,还应控制输入时的数字。 我建议这样做如下:

 #include  #include  #define NUM_OF_DATA 1048 int main(void) { printf("\n Welcome! \n\n Please enter each data point. Enter 'done' when finished.\n\n"); double data[NUM_OF_DATA]; int i; // counter of entered numbers char str[5] = { 0 }; // string to read 'done' or other word from input for (i = 0; i < NUM_OF_DATA; i++) // the first index of data in array is 0 (the last NUM_OF_DATA-1) { printf("Data[%i]: ", i); if (1 == scanf("%lf", &data[i])) // if number was successfully read continue; // go to next iteration // if some problem was with reading a loat number // read the string scanf("%4s", str); // read not more than 4 characters from input if ( strcmp(str, "done") == 0) { break; // stop input if 'done' was entered } // clean input buffer before next input while (getchar() != '\n'); // correct counter in case of wrong input i--; } // output the number of correct inputs printf("%d numbers were entered.\n", i); // do something with data // taking in account, that i is not index of the last element, // but the number of elements (indexes are 0 ... i-1) // ... return 0; } 

for循环在两种情况下停止:

1)当dataarrays已满时,

2)在没有输入引号'done'情况下'done'

附加function是跳过不正确的输入(尝试它是如何工作的)。

数据的数据类型是双倍的

 double data[1048]; 

而你将它与字符值等同起来。 这是一个类型错误。 如果要等同,请使用字符数据类型,而不是double。 Double是浮点类型。