【问题标题】:how to scanf unknown amount of integer numbers into array in C?如何将未知数量的整数扫描到C中的数组中?
【发布时间】:2017-04-19 17:45:28
【问题描述】:

我知道我可以用scanf scanf 一定数量的数字,例如 3 个数字

scanf("%d %d %d",array[0],array[1],array[2]);

但是,如果我不知道在输入之前将多少个数字(整数,而不是浮点数)输入到数组中(不是 EOF),我该如何扫描它?例如

input : 12 43 23(enter) --> array[0]=12, array[1]=43, array[2]=23
input : 10 20 30 40 50(enter) --> array[0]=10, array[1]=20, array[2]=30, array[3]=40, array[4]= 50
etc..

这是关于如何将数字输入到整数数组中。

如果可能的话,我想把它保存到一个二维数组中,例如

input : 12 43 23(enter) --> array[0][0]=12, array[0][1]=43, array[0][2]=23
input : 10 20 30 40 50(enter) --> array[1][0]=10, array[1][1]=20, array[1][2]=30, array[1][3]=40, array[1][4]= 50

【问题讨论】:

  • 阅读整行并以其他方式解析它? fgetsstrtol 函数可以用于此。
  • 等一下,你是在问如何制作一个大小合适的数组并在拥有它们后添加数字?
  • @iluvatar 是的,类似的东西,我不知道如何正确解释我想要什么。
  • 所以我应该用 [1000] 声明变量?那会浪费内存吧?
  • 动态内存在这里会派上用场。

标签: c arrays integer


【解决方案1】:

您可以使用while 循环并检查scanf 的返回值。例如:

int num = 0;
int idx = 0;
int arr[100] = { 0 };
while( scanf( "%d", &num ) == 1 )
{
    arr[idx++] = num;
    if( idx == 99 )  // protect from array overflow
    {
        break;
    }
}
for( int i = 0; i < idx; i++ )
{
    printf( "%d\n", arr[i] );
}

【讨论】:

  • 我不认为这是他们想要的......它不会扫描一行中的多个整数。
  • @Iluvatar 是的
  • 不,尽管它在一行上扫描多个整数。它不会按要求在“Enter (NOT EOF)”处终止。
  • 啊,确实如此,但是您必须输入一些导致 scanf 解锁的内容,因此仅按 Enter 不会这样做。
【解决方案2】:

以下是如何将事物存储在(动态分配的)数组中的方法。这确实假设行长度限制为 1000 个字符。 (代码改编自How do I use scanf() to take an arbitrary amount of integers?

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

int main() {
    int val_size = 2;
    int* vals = (int*)malloc(val_size * sizeof(int)); // initial array size
    char buffer[1000]; // for reading in the line
    int pos, bytes_read, num;
    int num_read = 0;

    if (fgets(buffer, sizeof(buffer), stdin) != 0) {
        for (pos = 0; sscanf(buffer+pos, "%d%n", &num, &bytes_read) != EOF; pos += bytes_read) {
            // resize the array if needed
            if (num_read >= val_size) {
                val_size *= 2;
                vals = (int*)realloc(vals, val_size * sizeof(int));
            }

            // store the value in the array
            vals[num_read] = num;
            num_read++;
        }
    }

    // print the values to prove it works
    for (int i = 0; i < num_read; i++) {
        printf("%d ", vals[i]);
    }
    printf("\n");

    free(vals); // important after you're done with it
}

您可以在 if 周围环绕一段时间以获得多行。

【讨论】:

  • 你不应该从 malloc/realloc 转换返回值。 stackoverflow.com/questions/605845/…
  • 这看起来像是一场宗教战争,是吗?或者至少与if (a == 0)if (0 == a) 相同?也许严格来说它可以缓解一些用户错误,这两种方式都有利有弊。
  • stackoverflow.com/a/14879184/3761456 诚然,它的支持率是第一名的十分之一,但它们仍然存在,而且在这一点上对我来说似乎主要是风格。
  • 老实说int *vals = malloc(val_size * sizeof *vals);看起来不像int* vals = (int*)malloc(val_size * sizeof(int));那么混乱
  • @lluvatar 我不买那个。这个问题标记为 C,而不是 C++。如果你在 C++ 中使用 malloc,你肯定做错了什么。
【解决方案3】:

下面的代码展示了如何将整数扫描到二维数组中:

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

#define INITSIZE 5
#define BUFFSIZE 1000

void print_and_free(int **array, int rowsize, int colsize);
void check_ptr(void *ptr, const char *msg);

int
main(void) {
    int **array;
    size_t rowsize = INITSIZE, colsize = INITSIZE;
    int row = 0, col, numdigits;

    char buffer[BUFFSIZE];
    char *number;

    array = malloc(rowsize * sizeof(*array));
    check_ptr(array, "Allocation");

    printf("Enter digits(Enter blank line to end):\n");
    while (fgets(buffer, BUFFSIZE, stdin) != NULL && strlen(buffer) != 1) {
        col = 0;
        numdigits = 0;
        if (rowsize == row) {
            rowsize *= 2;
            array = realloc(array, rowsize * sizeof(*array));
            check_ptr(array, "Reallocation");
        }

        array[row] = malloc(colsize *sizeof(int));
        check_ptr(array[row], "Allocation");

        number = strtok(buffer, " ");
        while (number != NULL) {
            numdigits++;
            if (colsize == numdigits) {
                colsize *= 2;
                array[row] = realloc(array[row], colsize * sizeof(int));
                check_ptr(array[row], "Reallocation");
            }
            array[row][col] = atoi(number);
            col++;
            number = strtok(NULL, " ");
        }
        row++;
    }

    print_and_free(array, row, col);

    return 0;
}

void
print_and_free(int **array, int rowsize, int colsize) {
    int row, col;

    printf("Your numbers:\n");
    for (row = 0; row < rowsize; row++) {
        for (col = 0; col < colsize; col++) {
            printf("array[%d][%d] = %d", row, col, array[row][col]);
            if (col != colsize - 1) {
                printf(", ");
            }
        } 
        free(array[row]);
        array[row] = NULL;
        printf("\n");
    }

    free(array);
}

void
check_ptr(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}

【讨论】:

  • 谢谢,顺便问一下size_t rowsize = INITSIZE, colsize = INITSIZE;是干什么用的?
  • 不用担心@juliussin。是的,他们刚刚开始从malloc 分配空间的大小。我只是假设5 将是一个很好的起始大小,如果您的数组最终变得更大,那么只需realloc 更多空间。如果需要,您可以将 size_t 替换为 int,这对您来说可能更清楚。
猜你喜欢
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多