如何解决随机数的无限打印? C语言

时间:2018-11-30 17:06:47

标签: c loops printf command-line-interface scanf

我写了一个程序,将未知数量的整数扫描到一个数组中,但是当我运行它时,它会打印出无数次的最后一个值。 例如,输入:1 2 3 4 5 输出为55555555555555555555555555 ... 为什么会发生这种情况,我该如何解决? 我的目标是为实例{1、2、3、4、5}创建一个数组,然后仅将扫描的内容打印到该数组中。

int *pSet = (int*) malloc(sizeof(int)); int i; int c;
printf("Please enter a stream of numbers to make a set out of them: ");
printf("\n");

scanf("%d", &c);
pSet[0] = c;
printf("%d ", c);
for(i = 1; c != EOF; i++) {
    pSet = (int*) realloc(pSet, sizeof(int)*(i+1));
    if(pSet == NULL) {
        return FAIL;        
    }
    scanf("%d", &c);
    pSet[i] = c;
    printf("%d ", c);
}

free(pSet);

谢谢。

3 个答案:

答案 0 :(得分:2)

  

为什么会这样(?)(打印...无限次。)

查看循环终止条件c != EOF

int c;
scanf("%d", &c);
for(i = 1; c != EOF; i++) {  // Not good code
  scanf("%d", &c);
}

EOF是一个负值,通常为-1。 scanf("%d", &c)尝试读取用户输入并转换为intscanf()返回10EOF,具体取决于是否1)成功,2)找不到数字文本或3)文件结尾或输入错误发生。不幸的是,代码没有使用该返回值。相反,代码使用读取的数字c,并检查读取的数字是否与EOF相同。


  

我该如何解决?

仅在scanf()的返回值符合预期(1)时循环。

for(i = 1; scanf("%d", &c) == 1; i++) {
  ...
}

将其与其他一些想法一起

#include <stdio.h>
#include <stdio.h>

int main(void) {
  printf("Please enter a stream of numbers to make a set out of them:\n");
  int *pSet = NULL;  // Start with no allocation
  size_t i = 0;

  int c;
  for (i = 0; scanf("%d", &c) == 1; i++) {
    //        +---------------------------  No cast needed.
    //        v               v----------v  Use sizeof de-referenced pointer
    void *p =   realloc(pSet, sizeof *pSet * (i + 1));
    if (p == NULL) {
      free(pSet);
      return EXIT_FAILURE;
    }
    pSet = p;
    pSet[i] = c;
  }

  for (size_t j = 0; j < i; j++) {
    printf("%d ", pSet[j]);
  }

  free(pSet);
  return 0;
}

答案 1 :(得分:1)

当scanf失败时,您应该停止循环。根据手册

  

成功后,[scanf] 返回成功匹配和分配的输入项目数;如果较早匹配失败,则该值可以小于所提供的值,甚至可以为零。   如果在第一次成功转换或匹配失败发生之前到达输入结束,则返回EOF值。如果发生读取错误,也会返回EOF。 [...]

因此您可以将for循环变成一会儿。

#include <stdio.h>
#include <stdlib.h>

#define FAIL 0
int main() {
  int *pSet = (int*) malloc(sizeof(int));
  int c;
  int i=0;
  printf("Please enter a stream of numbers to make a set out of them: ");
  while(scanf("%d", &c) == 1) {
    pSet[i] = c;
    pSet = (int*) realloc(pSet, sizeof(int)*(i+1));
    if(pSet == NULL) {
      return FAIL;        
    }
    printf("%d ", c);
    i++;
  }

  free(pSet);
}

但是,如果您需要一段更健壮的代码,建议您以字符串(由NULL终止的数组(char结束)的形式检索答案,然后使用诸如{ {1}},让您检查整个字符串是否是有效条目,而不仅是前几个字符。

答案 2 :(得分:1)

有很多问题。

1)当scanf失败而不是使用EOF时终止循环。为此,请检查返回值是否为1(即输入项的数量)        成功匹配)

2)在需要之前不要分配内存

3)从不直接在目标指针中执行realloc-始终使用临时变量。

修正此代码可能是:

#include <stdio.h>

int main(void) {
    int *pSet = NULL;
    printf("Please enter a stream of numbers to make a set out of them: ");
    printf("\n");

    int i = 0;
    int c;
    while (1) {
         if (scanf("%d", &c) != 1)
         {
             printf("Terminating input loop\n");
             break;
         }

         int* tmp = realloc(pSet, sizeof(int)*(i+1));
         if(tmp == NULL) {
            printf("oh dear...\n");
            break;
         }
         pSet = tmp;
         pSet[i++] = c;
         printf("%d ", c);
    }

    for (int j=0; j < i; ++j) printf("%d\n", pSet[j]);
    free(pSet);
    return 0;
}

输入:

1 2 3 4 5 6 7 stop

输出:

Please enter a stream of numbers to make a set out of them: 
1 2 3 4 5 6 7 
Terminating input loop
1
2
3
4
5
6
7