尝试获取用户输入以生成二维数组乘法表

问题描述 投票:1回答:2
int main (void)
{
    int range, i, j;

    printf("Input size of multiplication table: ");
    scanf("%i", &range);

    int output[range][range];

    for (i = 0; i<=range; ++i)
    {
        for (j=0; j<=range; ++j)
        {
            output[i][j] = i * j;
            if(j!=range && output[i][j] != 0)
            {
                printf("%3i ", output[i][j]);
            }
            else if (j==range)
            {
                printf("%3i", output[i][j]);
            }
            else if (output[i][j] == 0)
            {
                printf("%3i "), i+2;
            }
            else
            {
                printf("%3i", j + i - range);
            }
        }
        printf("\n");
    }    
    return 0;
}

我有它的输出:

0   1   2   3   4   0
5   1   2   3   4   5
10   2   4   6   8  10
15   3   6   9  12  15
20   4   8  12  16  20
25   5  10  15  20  25

我需要结尾的0是5,第一列是0,1,2,3,4,5而不是0,5,10,15,20,25。如果有人可以提供帮助,我会很感激。

c arrays nested tabular
2个回答
2
投票

您有两个主要问题,(1)您无法验证您的用户输入,以及(2)您的循环边界不正确,例如

每当您接受用户输入时,您必须验证您实际收到了预期的内容以及所需的任何转换是否已成功完成。未能验证将导致未定义的行为,它提供无效(或无)输入。 (例如,如果用户输入foo而不是10会怎样?)使用scanf时,您必须验证返回值,该返回值提供成功发生的转换次数,例如

    printf ("Input size of multiplication table: ");
    if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

这是最低限度的。您还可以检查返回是否为EOF以指示用户使用[Ctrl + D](或windoze上的[Ctrl + Z] - 取消输入 - 必须在Win10上明确启用)。

接下来,你的循环绑定是for (i = 0; i < range; i++)而不是i <= range,它通过尝试访问数组边界之外的内存来调用Undefined Behavior。只需修复循环条件,例如

    for (i = 0; i< range; i++) {    /* fill multiplication table */
        for (j = 0; j< range; j++) {
            output[i][j] = (i + 1) * (j + 1);   /* i+1 * j+1 */
        }
    }

完全放在一起,你可以做类似的事情:

#include <stdio.h>

int main (void) {

    int range, i, j;

    printf ("Input size of multiplication table: ");
    if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    int output[range][range];       /* variable length array */

    for (i = 0; i< range; i++) {    /* fill multiplication table */
        for (j = 0; j< range; j++) {
            output[i][j] = (i + 1) * (j + 1);   /* i+1 * j+1 */
        }
    }

    for (i = 0; i< range; i++) {    /* output table */
        for (j = 0; j< range; j++)
            printf (" %3d", output[i][j]);
        putchar ('\n');
    }

    return 0;
}

注意:省略了表的平凡部分(例如0 * anything),并且也没有显示重复的1 * anything行。如果需要其他行,可以将其添加回来。

示例使用/输出

$ ./bin/multable
Input size of multiplication table: 10
   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100

仔细看看,如果您有其他问题,请告诉我。


显示1X行

您只需按如下方式更新打印例程:

    for (i = 0; i< range; i++) {    /* output table */
        if (!i) {
            printf ("    ");
            for (j = 0; j< range; j++)
                printf (" %3d", output[i][j]);
            putchar ('\n');
        }
        printf (" %3d", i + 1);
        for (j = 0; j< range; j++)
            printf (" %3d", output[i][j]);
        putchar ('\n');
    }

示例使用/输出

$ ./bin/multable1
Input size of multiplication table: 10
       1   2   3   4   5   6   7   8   9  10
   1   1   2   3   4   5   6   7   8   9  10
   2   2   4   6   8  10  12  14  16  18  20
   3   3   6   9  12  15  18  21  24  27  30
   4   4   8  12  16  20  24  28  32  36  40
   5   5  10  15  20  25  30  35  40  45  50
   6   6  12  18  24  30  36  42  48  54  60
   7   7  14  21  28  35  42  49  56  63  70
   8   8  16  24  32  40  48  56  64  72  80
   9   9  18  27  36  45  54  63  72  81  90
  10  10  20  30  40  50  60  70  80  90 100

0
投票

检查下面的解决方案。这一切都是为了正确管理迭代器(注意范围中的等值符号越小,并且赋值中的索引减法为1)。您可以通过分配printf内部的输出并使用三元if来非常简洁地完成。 (我也使用动态分配以符合ISO标准。)

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

int main()
{
    int range, i, j;

    printf("Enter the size of the multiplication table:\n");
    scanf("%d", &range);

    int ** output = (int **) malloc(sizeof(int *) * (long unsigned int) range);

    for(i = 0; i <= range; ++i)
    {
        output[i] = (int *) malloc(sizeof(int) * (long unsigned int) range);

        for(j = 0; j <= range; ++j)
            printf("%3d ", !i ? j : !j ? i : (output[i - 1][j - 1] = i * j));

        printf("\n");
    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.