如何让程序在c语言中只接受正整数值

如何让程序在c语言中只接受正整数值,c,loops,C,Loops,编写一个程序,该程序将查找用户输入值的最小值、最大值、平均值。无法写入将检查以确保只输入正整数并生成错误消息的内容。下面是我目前正在读取输入的for语句: for (int value = 0; value <= numofvals; ++value) { printf("Value %d: %f\n", value, val_input); scanf("%f", &val_input); } for(int value=0;value一个简单且

编写一个程序,该程序将查找用户输入值的最小值、最大值、平均值。无法写入将检查以确保只输入正整数并生成错误消息的内容。下面是我目前正在读取输入的for语句:

  for (int value = 0; value <= numofvals; ++value) {
      printf("Value %d: %f\n", value, val_input);
      scanf("%f", &val_input);
  }

for(int value=0;value一个简单且可移植的解决方案

#include <limits.h>
#include <stdio.h>
int get_positive_number() {
  char buff[1024];
  int value, ch;
  while (1) {
    printf("Enter positive number: ");
    if (fgets(buff, 1023, stdin) == NULL) {
      printf("Incorrect Input\n");
      // Portable way to empty input buffer
      while ((ch = getchar()) != '\n' && ch != EOF)
        ;
      continue;
    }
    if (sscanf(buff, "%d", &value) != 1 || value < 0) {
      printf("Please enter a valid input\n");
    } else {
      break;
    }
  }
  return value;
}
void solution() {
  // Handling malformed input
  // Memory Efficient (without using array to store values)
  int n;
  int min = INT_MAX;
  int max = INT_MIN;
  double avg = 0;
  printf("Enter number of elements: ");
  scanf("%d", &n);
  getc(stdin);
  int value;
  for (int i = 0; i < n; i++) {
    value = get_positive_number();
    if (value > 0) {
      if (min > value) {
        min = value;
      }
      if (max < value) {
        max = value;
      }
      avg += value;
    }
  }
  avg = avg / n;
  printf("Min = %d\nMax = %d\nAverage = %lf\n", min, max, avg);
}
int main() {
  solution();
  return 0;
}
首先,.If
stdin
与它期望的不匹配,它将把它留在缓冲区中,继续读取相同的错误输入。调试是非常令人沮丧的

const int max_values = 10;

for (int i = 0; i <= max_values; i++) {
    int value;
    if( scanf("%d", &value) == 1 ) {
        printf("Got %d\n", value);
    }
    else {
        fprintf(stderr, "I don't recognize that as a number.\n");
    }
}
相反,请使用
fgets
可靠地读取整行,并使用
sscanf
解析整行。
%f
表示浮点数和十进制数。使用
%d
仅识别整数。然后检查是否为正

#include <stdio.h>

int main() {
    const size_t max_values = 10;
    int values[max_values];
    char buf[1024];

    size_t i = 0;
    while(
        // Keep reading until we have enough values.
        (i < max_values) &&
        // Read the line, but stop if there's no more input.
        (fgets(buf, sizeof(buf), stdin) != NULL)
    ) {
        int value;

        // Parse the line as an integer.
        // If it doesn't parse, tell the user and skip to the next line.
        if( sscanf(buf, "%d", &value) != 1 ) {
            fprintf(stderr, "I don't recognize that as a number.\n");
            continue;
        }

        // Check if it's a positive integer.
        // If it isn't, tell the user and skip to the next line.
        if( value < 0 ) {
            fprintf(stderr, "Only positive integers, please.\n");
            continue;
        }

        // We got this far, it must be a positive integer!
        // Assign it and increment our position in the array.
        values[i] = value;
        i++;
    }

    // Print the array.
    for( i = 0; i < max_values; i++ ) {
        printf("%d\n", values[i]);
    }
}
#包括
int main(){
常量大小最大值=10;
int值[最大值];
char-buf[1024];
尺寸i=0;
当(
//继续阅读,直到我们有足够的价值。
(i<最大值)&&
//读这行,但是如果没有更多的输入,就停下来。
(fgets(buf,sizeof(buf),stdin)!=NULL)
) {
int值;
//将该行解析为整数。
//如果没有解析,告诉用户并跳到下一行。
如果(sscanf(buf、%d、&value)!=1){
fprintf(stderr,“我不认为这是一个数字。\n”);
继续;
}
//检查它是否为正整数。
//如果不是,告诉用户并跳到下一行。
如果(值<0){
fprintf(stderr,“请仅限正整数。\n”);
继续;
}
//我们走了这么远,它一定是一个正整数!
//分配它并增加我们在数组中的位置。
数值[i]=数值;
i++;
}
//打印数组。
对于(i=0;i

请注意,由于用户可能输入错误的值,我们不能使用简单的for循环。相反,我们会循环,直到读取足够的有效值,或者没有更多的输入为止。

像这样简单的方法可能适合您:

int n;
int ret;

for (;;) {
    ret = scanf("%d", &n);

    if (ret == EOF)
        break;

    if (ret != 1) {
        puts("Not an integer");
        for (;;)
            if (getchar() == '\n')
                break;
        continue;
    }

    if (n < 0) {
        puts("Not a positive integer");
        continue;
    }

    printf("Correct value %d\n", n);

    /* Do your min/max/avg calculation */
}

/* Print your results here */
intn;
int ret;
对于(;;){
ret=scanf(“%d”和&n);
如果(ret==EOF)
打破
如果(ret!=1){
puts(“非整数”);
对于(;;)
如果(getchar()=='\n')
打破
继续;
}
if(n<0){
puts(“非正整数”);
继续;
}
printf(“正确值%d\n”,n);
/*进行最小/最大/平均值计算*/
}
/*在这里打印结果*/
这只是一个例子,假设您不需要读取浮点数,然后检查它们是否是整数,以及其他一些事情。但对于初学者来说,这很简单,您可以在上面工作


要打破循环,您需要传递
EOF
(在Linux/macOS终端中通常为Ctrl+D,在Windows终端中为Ctrl+Z)。

如何打印从
stdin
读取的
val\u输入
?读入值后,需要使用if-then语句来验证输入是否符合您的要求(更重要的是,您的程序)期望值。这是您在编程中花费大量工作的结果,因为无效输入可能会导致严重的安全问题和其他错误。基本规则是永远不要信任用户输入,始终验证所有内容。您还可以检查
如果((val\u input>>(sizeof val\u input*CHAR\u BIT-1))&1)
检查是否设置了符号位(位31表示单精度浮点和
int
或位63表示双精度浮点和8字节整数值)
CHAR\u bit
是每个字符的位数(通常为8)并且在
limits.h
中定义。如果一行中输入的数字超过1个,会发生什么?像
1.234
这样不是整数的数字输入会发生什么?不是我的下一票,而是…fseek(stdin,0,SEEK\u END)
行是非常有争议的。很多时候,
stdin
不是一个可查找的设备。由于一行中的错误而跳过整个输入文件可能太苛刻了。(有关此主题的详细信息,请参阅另一篇文章。)我还希望看到
printf(“%d\n”,n)
格式字符串末尾有换行符。这不会打印任何错误消息,也不会读取要处理的值,只需搜索第一个正确的值。最好使用
fgets
sscanf
然后尝试修补
scanf
。请注意,新代码(“一种简单的方法”)如果用户仅指示EOF(
n
未初始化使用),或者如果用户键入字母(或其他非数字字符)而不是数字,则会遇到问题。您必须检查
scanf()
中的返回值。如果
scanf()
返回EOF,您可能应该放弃循环;如果它返回
0
,您可能应该考虑读取字符直到下一个换行符,或者直到下一个可能是数字的字符-a
+
-
或读取整数时的数字。鲁棒输入非常困难。此代码没有定义输入格式错误时的行为,例如,如果用户输入字母而不是数字。@Acorn:如果您不处理交互式输入,则不需要提示。@Acorn可归结为“扫描缓冲区中的剩余内容”和“检查返回值”.太多了。太多了。@Acorn这表示人们被
scanf
的陷阱抓住的频率。@Acorn--“不要使用
scanf()
”这是一个非常好的建议,特别是对学习者来说。这个函数很难正确使用,而且有很多黑暗的角落,甚至那些知道自己在做什么的人都会被它的怪癖所吸引。几乎总是有比
scanf()
@Acorn>更好的解决方案,它更简单、更灵活。使用
#include <stdio.h>

int main() {
    const size_t max_values = 10;
    int values[max_values];
    char buf[1024];

    size_t i = 0;
    while(
        // Keep reading until we have enough values.
        (i < max_values) &&
        // Read the line, but stop if there's no more input.
        (fgets(buf, sizeof(buf), stdin) != NULL)
    ) {
        int value;

        // Parse the line as an integer.
        // If it doesn't parse, tell the user and skip to the next line.
        if( sscanf(buf, "%d", &value) != 1 ) {
            fprintf(stderr, "I don't recognize that as a number.\n");
            continue;
        }

        // Check if it's a positive integer.
        // If it isn't, tell the user and skip to the next line.
        if( value < 0 ) {
            fprintf(stderr, "Only positive integers, please.\n");
            continue;
        }

        // We got this far, it must be a positive integer!
        // Assign it and increment our position in the array.
        values[i] = value;
        i++;
    }

    // Print the array.
    for( i = 0; i < max_values; i++ ) {
        printf("%d\n", values[i]);
    }
}
int n;
int ret;

for (;;) {
    ret = scanf("%d", &n);

    if (ret == EOF)
        break;

    if (ret != 1) {
        puts("Not an integer");
        for (;;)
            if (getchar() == '\n')
                break;
        continue;
    }

    if (n < 0) {
        puts("Not a positive integer");
        continue;
    }

    printf("Correct value %d\n", n);

    /* Do your min/max/avg calculation */
}

/* Print your results here */