Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何修复随机数的无限打印?_C_Loops_Printf_Command Line Interface_Scanf - Fatal编程技术网

C 如何修复随机数的无限打印?

C 如何修复随机数的无限打印?,c,loops,printf,command-line-interface,scanf,C,Loops,Printf,Command Line Interface,Scanf,我写了一个程序,将未知数量的整数扫描到一个数组中,但当我运行它时,它会打印出它得到无限次的最后一个值 例如输入:1 2 3 4 5 输出将是555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555 为什么会发生这种情况?我如何解决 我在这里的目标是创建一个数组,例如一个实例{1,2,3,4,

我写了一个程序,将未知数量的整数扫描到一个数组中,但当我运行它时,它会打印出它得到无限次的最后一个值

例如输入:1 2 3 4 5

输出将是555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555

为什么会发生这种情况?我如何解决

我在这里的目标是创建一个数组,例如一个实例{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);

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

成功时,[scanf]返回[s]成功匹配和分配的输入项目数;在早期匹配失败的情况下,该值可能小于规定值,甚至为零。 如果在第一次成功转换或匹配失败发生之前到达输入端,则返回值EOF。如果发生读取错误,也会返回EOF。[……]

因此,您可以将for循环转换为while循环

#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;
    pSetNew = (int*) realloc(pSet, sizeof(int)*(i+1));
    if(pSetNew == NULL) {
      free(pSet);
      return FAIL;        
    } else {
      pSet = pSetNew;
    }
    printf("%d ", c);
    i++;
  }

  free(pSet);
}
但是,如果您想要一段更健壮的代码,我建议您将答案检索为以字符串NULL结尾的字符数组,然后使用诸如strtol之类的专用函数对其进行解析,该函数允许您检查整个字符串是否为有效条目,而不仅仅是第一个字符


注意:HengLi修复了上面代码示例中的一个潜在内存泄漏

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

成功时,[scanf]返回[s]成功匹配和分配的输入项目数;在早期匹配失败的情况下,该值可能小于规定值,甚至为零。 如果在第一次成功转换或匹配失败发生之前到达输入端,则返回值EOF。如果发生读取错误,也会返回EOF。[……]

因此,您可以将for循环转换为while循环

#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;
    pSetNew = (int*) realloc(pSet, sizeof(int)*(i+1));
    if(pSetNew == NULL) {
      free(pSet);
      return FAIL;        
    } else {
      pSet = pSetNew;
    }
    printf("%d ", c);
    i++;
  }

  free(pSet);
}
但是,如果您想要一段更健壮的代码,我建议您将答案检索为以字符串NULL结尾的字符数组,然后使用诸如strtol之类的专用函数对其进行解析,该函数允许您检查整个字符串是否为有效条目,而不仅仅是第一个字符


注意:恒力修复了上述代码示例中可能存在的内存泄漏问题。

存在许多问题

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;
}
输出:

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

有许多问题

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;
}
输出:

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
为什么会发生这种情况。。。无数次

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

EOF是一些负值,通常为-1。scanf%d,&c尝试读取用户输入并将其转换为整数。scanf返回1,0,EOF,具体取决于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;
}
为什么会发生这种情况。。。无数次

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

EOF是一些负值,通常为-1。scanf%d,&c尝试读取用户输入并将其转换为整数。scanf返回1,0,EOF,具体取决于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;
}

你从不检查scanf是否真的有效。我试图根据你发送的内容修复我的输入,但它没有改变任何东西。我发送给程序:1 2 3 4 5 Enter@BurnsBAIf scanf不起作用变量c不会被初始化。程序打印c,打印时c为5。我几乎不认为这是问题所在。。。不过还是要谢谢你@Andrewhenla在这几行基本上是自包含的代码中的一个问题天生就是调试器中的单步执行。不要忽略那些scanf调用的结果,以免违反。最后,我要求您指出,在中,它表示填充整数格式ou的位置

tput参数与EOF在流命中时所说的相同,因为不存在这样的行为。简短版本:阅读并理解您正在使用的函数的要求。删除不必要的[未解决]标题编辑。已解决或未解决,标题不需要更改。您从未检查scanf是否实际工作。我尝试根据您发送的内容修复输入,但它没有更改任何内容。我发送给程序:1 2 3 4 5 Enter@BurnsBAIf scanf不起作用变量c不会被初始化。程序打印c,打印时c为5。我几乎不认为这是问题所在。。。不过还是要谢谢你@Andrewhenla在这几行基本上是自包含的代码中的一个问题天生就是调试器中的单步执行。不要忽略那些scanf调用的结果,以免违反。最后,我要求您指出,在中,它指出一旦流达到相同的值,它就会用EOF填充整数格式的输出参数,因为不存在这样的行为。简短版本:阅读并理解您正在使用的函数的要求。删除不必要的[未解决]标题编辑。已解决或未解决,标题无需更改。temp第17行中的realloc每次都失败@4386427我更改了您的代码,您编写的一些内容不符合C语法@4386427@ShadowOverLoad您特别发现了哪些不符合C语法的内容?您使用的是什么当前版本的C?我怀疑这是一个20年前的版本。这个答案是有效的C.@shadow重载不是根据C语法什么?请澄清我在修复代码后发送的代码。例如,在C语言中,编译器不允许您在一个循环中同时定义和初始化所有内容,就像您在数组tmp中所做的那样@温度线17中的4386427realloc每次都失败@4386427我更改了您的代码,您编写的一些内容不符合C语法@4386427@ShadowOverLoad您特别发现了哪些不符合C语法的内容?您使用的是什么当前版本的C?我怀疑这是一个20年前的版本。这个答案是有效的C.@shadow重载不是根据C语法什么?请澄清我在修复代码后发送的代码。例如,在C语言中,编译器不允许您在一个循环中同时定义和初始化所有内容,就像您在数组tmp中所做的那样@4386427对于输入1 2 3 4 5,输出为:1 0 2 130017 3 130009 4 130001 5 129993@chux@ShadowOverLoad代码修改-删除输入1 2 3 4 5的额外+,输出为:102130017313000941300015129993@chux@ShadowOverLoad代码已修改-删除“./catch”中的额外+++***错误:realloc:下一个大小无效:0x088c8008**@Amessihel@ShadowOverLoad最好搜索与此问题相关的现有答案,或提出一个准确描述您的环境的新问题,避免创建重复。代码中可能存在内存泄漏问题。当realloc找不到足够的空间来分配时,它将返回NULL并保持原始空间已分配。这显示了如何通过使用新变量来保存realloc.**Error in`./catch:realloc:invalid next size:0x088c8008**@Amessihel@ShadowOverLoad最好搜索与此问题相关的现有答案,或提出一个准确描述您的环境的新问题,避免创建重复。代码中可能存在内存泄漏问题。当realloc找不到足够的空间来分配时,它将返回NULL并保持原始空间已分配。这显示了如何通过使用新变量来保存realloc的返回来解决问题。