从用户获取数字并填充Matrix的有效方法

时间:2017-11-24 12:26:39

标签: c

我希望numbers中的single line获得2 1 2 3 4 ,例如:

number

第一个2Matrix表示我的2x2大小应为Matrix,接下来的4个数字应插入我的Matrix({ {1}}尺寸应为)。

目前我有这个:

int dimension, num;
int *mat;
int numcounter = 0;
int i = 0;
int j, k, t;
char temp;

printf("Please enter numbers: ");
do {
    scanf("%d%c", &num, &temp);
    i++;        
    if (i == 1)
    {
        /* Set Matrix dimension. */
        dimension = num;
        if (dimension < 2)
        {
            printf("Size must be a valid number");
            return 1;
        }
        else
            /* Allocate dimension size. */
            mat = (int*)malloc(dimension * dimension * sizeof(int*));

    }
    else
    {
        /* Fill Matrix. */          
    }

} while (temp != '\n' || temp == EOF)

所以这里我有所有号码,现在我需要填写Matrix,但不是将所有数字都放在temp array中,然后填写我的Matrix我想知道怎么做没有其他内存分配。

1 个答案:

答案 0 :(得分:1)

您只需使用VLA即可。 OP的初始问题从未提及OP需要在一行中获取输入并进行解析。我在第二部分给出了答案。但这不是必需的。您必须立即获得numbers所有这一切并不是一个可行的理由。您可以使用一个scanf获取大小,然后使用另一个scanf中的元素。

scanf("%d", &num);
//Then you know the dimension of the array.

int arr[num][num];
for(size_t i=0;i<num; i++)
  for(size_t j =0; j< num; j++)
     if( scanf("%d",&arr[i][j]) != 1)
     {
        fprintf(stderr,"Error in input");
        exit(1);
     }

另如您知道将会读取多少个数字,在获得'\n'EOF之前,您无需继续扫描。

鉴于你的情况你的过于复杂的东西恕我直言。如您所知,您可以从VLA中获益。

如果必须在一行中获取所有数字,则需要查看3个函数。 fgets()strtol。这些将帮助您在一行中阅读所有内容然后进行标记。

为了演示我所说的你可以做到的事情

#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 256

int main(void)
{
    char line[BUFSIZE];
    long temp[BUFSIZE];
    int i = 0;
    if (fgets(line, sizeof line, stdin) != NULL)
    {
        const char *ptr = line;
        while (*ptr != '\0')
        {
            char *endptr = NULL;
            long val = strtol(ptr, &endptr, 10);
            if (endptr != ptr)
              temp[i++] = val;
            else
                break;
            ptr = endptr;
        }
    }
    int sz = temp[0];
    if( sz <= 0 )
    {
        fprintf(stderr,"Error in size input");
        exit(1);
    }
    int tempIn = 1;
    long arr[sz][sz];
    for(size_t i = 0; i < sz; i++)
        for(size_t j = 0; j < sz; j++)
            arr[i][j]= temp[tempIn++];

    for(size_t i = 0; i < sz; i++)
        for(size_t j = 0; j < sz; j++)
            printf("%ld ",arr[i][j]);

}

在第二个代码中,您可以看到fgets已经被使用,它基本上读了一行,然后使用了strtol。正如您所提到的,您将提供一行数字输入。

现在我们做了什么?

使用strtol扫描的行和按编号分类的数字。有关strtol支票this的简要概述。

OP也询问如何使用动态内存分配来做同样的事情。而且这里不需要while循环。这是多余的。因此,在修改时,我将添加能够以更简单的方式执行此操作的代码。

scanf("%d", &num);
int matIndex = 0;      
/* Set Matrix dimension. */
dimension = num;
if (dimension <= 0)
{
    printf("Size must be posiitve integer");
    return 1;
}
else
{
    mat = malloc(dimension * dimension * sizeof *mat);
    if ( mat == NULL ){
        fprintf(stderr, "%s\n", "Error in malloc");
        exit(1);
    }
}

// All the numbers will be taken as elements of the dynamically allocated array,
for(size_t i = 0; i < dimension*dimension ; i++)
    if( scanf("%d",&mat[i]) == 1){
         //ok
    }
    else{
        fprintf(stderr,"Some error occured");
        break;
    }

如果您想访问i-th row and j-th column元素,可以执行此操作mat[i*dimension+j] // equivalent to mat[i][j]

一些有用的信息: -

  • 分配dim*dim内存不允许您以mat[i[[j]的形式访问该元素。因为你分配了一块内存 - 你必须明确地计算位置并访问线性数组中的元素。

  • 您可以使用scanf()进行所有扫描,但在scanf()时需要小心。但是,你也可以使用scanf来完成这件事。

  • 还有另一件事需要了解。 VLA将具有自动存储持续时间并限制您可以使用这种方式使用的内存。动态分配的内存具有更高的限制,使您可以拥有更大尺寸的数组。

  • 请注意,在动态内存分配中,当您使用它时,您需要free分配的内存。

  • 如果您想使用mat[i][j]而不是mat[i*dim+j],可以考虑创建一个jagged array

您需要的几件事情:

阅读建议: