【问题标题】:C Storing Matrix in Array of Chars and PrintingC将矩阵存储在字符数组中并打印
【发布时间】:2014-05-05 16:32:25
【问题描述】:

大家好,我正在尝试将矩阵存储在字符数组中,然后将其打印出来。

我写的代码:

#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

我无法弄清楚我的代码出了什么问题,我无法弄清楚我是如何在一个循环中退出迭代的,或者它与没有正确处理新行有关。谢谢!

【问题讨论】:

  • char数组在哪里?为什么char c?为什么不int c? C 中不允许使用 AFAIK 空初始化程序 (int array[3][2] = {{}};)。
  • 你能向我解释一下我的代码是如何工作的吗?此外,当我更改为 int c 并打印出 int 而不是 chars 时,我相信它打印的是地址编号,而不是存储在每个数组中的元素。
  • 应该是array[3][4]

标签: c arrays matrix printing io


【解决方案1】:

我能看到的几个问题是:

  1. 正如 cmets 中提到的 user3386109,您的数组应为 array[3][4] 以匹配输入文件。
  2. array[col++][row]; 行只增加col,然后无用地索引数组并丢弃该值。你可以用col++; 做同样的事情。但是,您甚至不会在代码中的任何后期使用col,所以实际上您甚至不需要它。 break; all 本身就可以满足您的需求。这让我...
  3. 您并没有像您认为那样填充数组。您正在增加col,然后立即跳出循环。那么整个数组是如何被填充的呢?纯属运气。事实证明,您的数组声明为array[3][4],数组访问array[0][4](在技术上甚至不应该存在)等同于array[1][0]。这是因为所有多维数组(在 C 和几乎任何其他语言中)都作为平面数组在内存中布局,因为内存本身使用线性寻址。在 C 中,这种多维数组的扁平化是在所谓的Row-major order 中完成的,这意味着当您从第一个地址到最后一个地址遍历原始内存时,相应的多维索引(i、j、k、...z 或 in您的情况只是 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 不会为您进行数组边界检查,因为它假设您正在自己做)。
  4. 这只是个人喜好,但您通常会看到引用为array[row][col] 的数组,而不是array[col][row]。但就像我说的,这只是偏好。如果您更容易将其可视化为[col][row],那么请务必这样做。只需确保您始终如一地执行此操作,并且不要在您的代码中途意外切换到执行[row][col]
  5. 如果您不小心在其中一行数字的末尾添加了一个尾随空格,您的代码将中断并且仅打印出部分矩阵,因为您检查输入结尾的奇怪方式(执行第二个getchar 在每个初始getchar 之后,并检查第二个字符是否为\n)。这种方法本身并没有错误,因为它可以工作,但它不是很健壮,并且依赖于您的输入数据被精确格式化并且不包含尾随空格。任何曾经花费数小时试图弄清楚为什么他们的 Makefile 不起作用,却发现这是因为他们有前导空格而不是制表符的任何人都可以证明,这些类型的错误可能非常耗时,而且令人沮丧的追查。精确格式化的输入数据总是一件好事,但是当您的代码没有得到完美的输入时,它不应该以不明显的方式意外中断(例如只打印出一半的矩阵) . 编辑:我后来才想到你实际上是打算在这里做两件相互排斥的事情:为下一行输入增加col,然后中断(大概)检测到输入结束后的循环。您需要弄清楚您在这里做什么,尽管多亏了第 3 项,您的代码实际上(并且奇怪)只需接受 user3386109 的建议并将array[3][2] 更改为array[3][4] 即可工作。
  6. 我只能假设您在 for 循环中分别使用了 &lt;= 2&lt;= 3 而不是 &lt; 3&lt; 4,因为您更喜欢这样做。这很好,但如果您的 for 循环条件与您的数组尺寸匹配,它通常会使代码更易于阅读。只是在这里推测,但也许这就是为什么你有array[3][2],而你真正的意思是array[3][4]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多