使用C中的scanf接收用户提供的尽可能多的输入

时间:2014-03-01 05:34:22

标签: c scanf

如果您不知道他们会给出多少输入,您如何接受用户提供的尽可能多的输入?这将是:

1 2 3
4 5
6 

我只需要一种方法来读取所有这些整数,而不设置任何限制。

2 个答案:

答案 0 :(得分:4)

可能是这样的: -

int input;

while (fscanf(stdin, "%d", &input) ==1) //Loop terminates on error or EOF
{
  /* process each input 
     Store in array or whatever
  */
}

答案 1 :(得分:0)

您是否需要在数组中一次存储所有整数,还是可以在读取时处理每个整数?第一行有三个整数,第二行有两个整数,或者那是不相关的,这有什么意义吗?

如果您不需要一次存储所有整数,并且您不需要知道何时到达行尾,那么scanf()fscanf()将正常工作。

int value;
while (scanf("%d", &value) == 1)
    process(value);

如果需要将所有整数存储到数组中,但不需要担心换行发生的位置,那么您可能需要使用动态内存分配以使数组增长。那是个小问题:

int *array = 0;
size_t a_size = 0;
size_t a_used = 0;
int value;

while (scanf("%d", &value) == 1)
{
    if (a_used == a_size)
    {
        size_t n_size = (a_size + 1) * 2;
        int *n_data = realloc(array, n_size * sizeof(*n_data));
        if (n_data == 0)
            …handle memory allocation failure…
        a_size = n_size;
        array = n_data;
    }
    array[a_used++] = value;
}

for (size_t i = 0; i < a_used; i++)
    printf("[%zu] = %d\n", i, array[i]);

请注意,“句柄内存分配失败”代码应该中止处理,可能还会释放当前分配的数组,或者可能只是继续使用现有数组进行处理(break会起作用)。注意代码如何通过将数组中的内存加倍来避免过多的复制,并且通过不从realloc()分配返回值直到知道非空为止来避免泄漏内存。如果你担心最后的内存分配过多,你可以在循环后进行'缩小'realloc(),指定数组的最终大小。

如果事实上你需要知道换行的位置,那么你必须更加努力地工作。您需要保留一组动态数组;你需要记录每条线的长度;而你必须停止使用scanf()fscanf(),因为他们并不关心线条。您使用fgets()readline()来读取一行(在fgets()的情况下,您需要担心是否有整行),然后您将使用sscanf()迭代解析整行。