嘿所有我试图将一个矩阵存储在一个字符数组中,然后将其打印出来。
我写的代码:
#include<stdio.h>
#include<stdlib.h>
int main() {
int i;
int j;
int row=0;
int col=0;
int temp=0;
char c;
int array[3][2] = {{}};
while((c=getchar()) !=EOF && c!=10){
if((c==getchar()) == '\n'){
array[col++][row];
break;
}
array[col][row++]=c;
}
for(i=0; i<=2; i++){
for(j=0; j<=3; j++){
printf("%c ", array[i][j]);
}
printf("\n");
}
}
使用文本文件,例如:
1 2 3 4
5 6 7 8
9 1 2 3
我希望能够将其打印回给用户,但我的代码输出的是:
1 2 3 4
3 4 5 6
5 6 7 8
我无法弄清楚我的代码有什么问题,有些我如何在我的一个循环中进行迭代,或者它与未正确处理新行有关。谢谢!
答案 0 :(得分:2)
我能看到的一些问题是:
array[3][4]
以匹配输入文件。array[col++][row];
除了递增col
之外什么都不做,然后无用地索引数组并抛弃该值。你可以用col++;
做同样的事情。但是,您甚至在代码的任何后期都没有使用col
,所以您甚至不需要这样做。 break;
本身就可以满足您的需求。这导致我... col
,然后立即退出循环。那么整个阵列如何填充?只是靠纯粹的运气。事实证明,您的数组声明为array[3][4]
,数组访问array[0][4]
(技术上不应该存在)等同于array[1][0]
。这是因为所有多维数组(在C和几乎任何其他语言中)都作为平面数组布局在内存中,因为内存本身使用线性寻址。在C中,多维数组的这种扁平化是在所谓的Row-major order中完成的,这意味着当你从第一个地址到最后一个地址遍历原始内存时,相应的多维索引(i,j,k,... z,或者在你的情况下只是i,j)以最后一个索引将变化最快的方式递增。因此,col
不仅会在您退出循环之前永远不会增加,但row
永远不会重置为0,这意味着您将array[0][0], array[0][1], ... array[0][11]
中的值存储起来正如您所期望的那样,不 array[0][0] .. array[0][3], array[1][0] .. array[1][3], array[2][0] .. array[2][3]
。幸运的是,由于行主要排序,这两组索引实际上是等价的(并且C不会对你进行数组边界检查,因为它假设你自己做了)。array[row][col]
的数组,而不是array[col][row]
。但就像我说的那样,这只是偏好。如果您更容易将其可视化为[col][row]
,那么无论如何都要这样做。只需确保您始终如一地执行此操作,并且不要在代码中途意外切换到[row][col]
。getchar
之后执行第二次getchar
并检查第二个字符是否为\n
)。这个方法本身并不是错误的,从某种意义上来说它是可行的,但它不是非常强大,并且依赖于您的输入数据被精确格式化并且不包含尾随空格。任何曾经花费数小时试图弄清楚为什么他们的Makefile不起作用的人,只是发现它是因为他们有前导空格而不是制表符可以证明这些错误可能是非常时间的事实 - 跟踪消耗和沮丧。精确格式化的输入数据总是一件好事,但是当不获得完美的输入。 编辑:以后我才发现你实际上打算在这里做两个相互排斥的事情:为下一行输入增加col
,并且在(可能)检测到输入结束后突然退出循环。你需要弄清楚你在这里做了什么,虽然多亏了第3项,你的代码实际上(以及奇怪的)只是通过获取user3386109的建议并改变{{ 1}}到array[3][2]
。array[3][4]
循环中使用了<= 2
和<= 3
而不是for
和< 3
,因为您更喜欢这样做办法。这没关系,但如果您的< 4
循环条件与您的数组维度匹配,通常会使代码更容易阅读。只是在这里猜测,但也许这就是为什么当你真正意味着for
时array[3][2]
{。}}。