我写了一个程序,将未知数量的整数扫描到一个数组中,但是当我运行它时,它会打印出无数次的最后一个值。 例如,输入: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);
谢谢。
答案 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)
尝试读取用户输入并转换为int
。 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;
}
答案 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