2

我正在尝试用 C 编写一个代码,它只是要求用户输入一个数字,该数字将用于创建一个矩阵 (D*D);然后插入字符然后打印。

这就是我写的:

int d; //matrix size
int i,k; // used for the loops
char **mat; // pointer to a pointer to char

printf("\nenter matrix size\n"); // size of the X*X matrix
scanf("%d",&d);

mat=(char **)malloc(d*sizeof(char *));

for (i=0;i<d;i++)
    mat[i]=(char *)malloc(d*sizeof(char));


printf("enter %d strings with length %d\n",d,d);

for (i=0;i<d;i++)
    for (k=1;k<=d;k++)
    mat[i][k]=getchar();

for (i=0;i<d;i++)
        for (k=0;k<d;k++)
        printf("%c",mat[i][k]);

--如果我输入 d=3 它会吓坏并进入一个无限循环 --如果我输入 5 例如它只给我 3 次输入 4 个字符而不是 4 个字符。

谢谢大家!

4

2 回答 2

2

这超出了数组的末尾,并导致未定义的行为:

for (i=0;i<d;i++)
    for (k=1;k<=d;k++)       /* this terminating condition */
        mat[i][k]=getchar(); 

我不确定为什么k从 0 开始,因为它会跳过正在读取的数组中的第一个字符。改成:;

for (i=0;i<d;i++)
    for (k=0;k<d;k++)
        mat[i][k]=getchar(); 

请注意,强制转换的返回值malloc()是不必要的(请参阅Do I cast the result of malloc?)并且sizeof(char)保证为 1。始终检查输入操作的结果scanf(),以确保变量已实际分配:

if (1 == scanf("%d",&d))
{
    mat = malloc(d * sizeof(char*));
    if (mat)
    {
        /* ... */
    }
}

stdin请注意,由于输入维度而输入的换行符将stdin在调用 后保留scanf()。这需要跳过,以防止干扰后续getchar()调用。跳到行尾:

int ch; /* Note that getchar() returns an int, not a char */
while ((ch = getchar()) != '\n' && ch != EOF);

如果用户使用换行符终止正在输入的字符串,那么在读取字符串时您还需要跳过它:

for (i=0;i<d;i++)
{
    for (k=0;k<d;k++)
    {
        int ch = getchar();
        if (EOF == ch)
        {
            fprintf(stderr, "Failed to read stdin");
            break;
        }
        mat[i][k]= (char) ch;
    }
    while ((ch = getchar()) != '\n' && ch != EOF);
}
于 2012-10-23T14:24:16.030 回答
0

我在 ubuntu 中使用 gcc 在我的环境中尝试过,当我使用 getchar 向用户询问矩阵字符值时,我面临的唯一问题是 End Line Characted,因为当用户输入字符时,它将按 Enter 键它的下一个值作为结果在标准输入中询问 \n 缓冲区,它将成为第二个输入字符。因此,当我输入 2 时,程序只要求矩阵输入 2 而不是 4。所以你可以这样做喜欢:

for (i = 0; i < d i++)
{
   for ( k = 0; k < d; k++)
   {
        getchar();
        mat[i][k] = getchar();
   }

}

请参阅 k 的 for 循环。应该是这样的。在您的情况下,您正在使用不正确的 k <= d 访问不存在的内存

于 2012-10-23T15:37:52.380 回答