【问题标题】:Row-major ordering in C as Command Line ArgumentC中的行主要顺序作为命令行参数
【发布时间】:2020-07-31 11:50:18
【问题描述】:

我需要从命令行通过一个如下所示的 txt 文件传入一个 2D 区域(矩阵):

0 0 0 0 0
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0
0 0 0 0 0

我正在使用 C 并且需要以行优先顺序使用它,所以我正在尝试这样做:

int matrix[][] = argv[2]; // it is the second command line argument passed

这不起作用,是因为它需要是一维数组吗?我是否只允许使用常规一维数组进行行优先排序? 我得到的错误是“数组类型有不完整的元素类型'int []'”

【问题讨论】:

  • 您需要循环读取文件,分配给数组元素。而且你必须声明数组的大小。
  • argv[2] 是你的文件名吗?
  • argv 是一个指向 char 的指针数组 => argv[2] 是一个字符串(如果有足够的参数),而不是 int
  • 当你声明一个多维数组时,你必须指定除第一个维度之外的所有维度的大小,你不能使用[][]。
  • “从注释行到 txt 文件”是什么意思?正如斯塔克所问的,argv[2] 是具有您在问题中给出的内容的文件的名称?二维数组总是 5x5 吗?

标签: c arrays matrix command-line-arguments row-major-order


【解决方案1】:

我正在尝试这样做:

int matrix[][] = argv[2]

这行不通,

因为这是无效的,所以缺少了';' :

  • 至少必须给出第二个维度,这就是为什么你有错误array type has compatible element type 'int[]'
  • matrix 是 int 的(错误定义的)二维数组,但在最好的情况下 argv[2] 是 char 的数组:
    • 如果程序在没有参数的情况下被调用 argv[2] 是未定义的
    • 如果用一个参数调用程序 argv[2] 为 NULL
    • 如果调用程序时至少使用 2 个参数 argv[2] 是包含第二个参数的字符串

考虑到 argv[2] 是包含 5x5 矩阵的文件的路径名,矩阵的声明可以是:

int matrix[5][5];

并且需要读取文件中的值来设置矩阵的内容,不能直接将txt文件映射到矩阵

例子:

#include <stdio.h>

int main(int argc, char ** argv)
{
  FILE * fp;

  if (argc < 3) {
    fprintf(stderr, "usage: %s ?? <file>\n", *argv);
    return -1;
  }
  else if ((fp = fopen(argv[2], "r")) == NULL) {
    perror("cannot open file");
    return -1;
  }
  else {
    int matrix[5][5];
    int i, j;

    for (i = 0; i != 5; ++i) {
      for (j = 0; j != 5; ++j) {
        if (fscanf(fp, "%d", &matrix[i][j]) != 1) {
          fprintf(stderr, "invalid file for [%d][%d]\n", i, j);
          return -1;
        }
      }
    }

    fclose(fp);

    /* debug */
    for (i = 0; i != 5; ++i) {
      for (j = 0; j != 5; ++j)
        printf("%d ", matrix[i][j]);
      putchar('\n');
    }

    putchar('\n');

    /* you can also use it as a 1D array */
    for (i = 0; i != 25; ++i) {
      printf("%d ", ((int *) matrix)[i]);
      if (i%5 == 4)
        putchar('\n');
    }

    return 0;
  }
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall a.c
pi@raspberrypi:/tmp $ cat f
0 0 0 0 0
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0
0 0 0 0 0
pi@raspberrypi:/tmp $ ./a.out whatever f
0 0 0 0 0 
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0 
0 0 0 0 0 

0 0 0 0 0 
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0 
0 0 0 0 0 
pi@raspberrypi:/tmp $ 

【讨论】:

  • 这更有意义,感谢您的帮助! fscanf(fp, "%d", &matrix[i][j]) != 1 是负责将txt文件读入矩阵的那一行吗?
  • @George 是的,如果在文件描述符 fp 指定的位置处的文件中存在有效的 int 外部表示,则可能在空格(空格、 tab, newline ...) 对应的 int 被保存到 matrix[i][j] int 表示之后的文件描述符进度,返回 1 (1 因为格式 "%d " 请求读取 1 个元素),否则 fp 不会在文件中进行并且 matrix[i][j] 未设置且 0 或 EOF 返回。我不必处理空格和换行符,因为格式 %d 之前会绕过它们来(尝试)读取数字
  • 感谢您的帮助!但是 fprintf(stderr, "invalid file for [%d][%d]\n", i, j);而且 fclose 也给了我分段错误。一旦我将它们注释掉,一切都会运行。知道为什么吗?
  • @George 您对我的代码做了哪些更改?对我来说,您使用更大的最大索引(我的意思是超过 5 个),但您没有更改矩阵的维度 => 您用未定义的行为写出它 => 在您的情况下出现分段错误
  • @George 如果程序的参数只是你必须从我的代码中将 argv[2] 替换为 argv[1] 的文件
【解决方案2】:

作为@bruno 的回答,您在声明二维数组时是错误的。我只是提出一种解决方案来使用双指针从输入文件中获取信息(如果您之前不知道数组的大小(行数,列数),请使用它。

您可以使用fgets 在文本文件中逐行获取。然后使用strtok 函数以空格分隔行。要从字符串中获取整数值,可以使用atoi函数。

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char line[256];
    int ** matrix = malloc(sizeof(int *));
    if(!matrix)
        return -1;
    if (argc < 2) {
        return -1;
    // argv[1] is the name of input file, for example input.txt
    FILE * fp = fopen(argv[1], "r");
    int row = 0, col;
    while(fgets(line, sizeof(line), fp)) {
        col = 0;
        matrix[row] = malloc(sizeof(int));
        if(!matrix[row])
            return -1;
        char * token = strtok(line, " ");

        while(token != NULL) {
             matrix[row][col] = atoi(token);
             token = strtok(NULL, " ");
             col++;
             // increase the size of each line after each loop
             matrix[row] = realloc(matrix[row], (col+1) * sizeof(int));
             if(!matrix[row])
                return -1;
        }
        row++;
        // increase size of matrix after each loop
        matrix = realloc(matrix, (row+1)*sizeof(int *));
        if(!matrix)
            return -1;
    }

    for(int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf("%d ", matrix[i][j]);
        }

        printf("\n");
    }
    return 0;
}

测试:

#cat input.txt
0 0 0 0 0 
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0 
0 0 0 0 0

./test input.txt
0 0 0 0 0 
0 1 1 0 0 
0 0 1 0 0 
0 0 1 0 0 
0 0 0 0 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 2016-02-22
    • 2018-10-05
    • 2015-12-26
    • 1970-01-01
    相关资源
    最近更新 更多