【问题标题】:2d dynamic arrays sent to a function in C2d 动态数组发送到 C 中的函数
【发布时间】:2015-03-29 20:37:47
【问题描述】:

此代码的目的是查看未知大小(从文件中读取)的二维数组(矩阵)是否有一个对角线,该对角线的数字都是相同的。如果是这样,函数 checkdiag 应该返回 1。

我正在使用的文件中的数据如下:

3

4 5 6

7 8 9

3 6 7

其中最初的 3 代表矩阵的大小,(3x3)

我知道它会运行并从文件中收集数据,因为它使用 fscanf 在 for 循环中打印矩阵。但每次超出此范围时,它都会崩溃。 我已经尝试了很多将变量传递给函数的方法,并对发生的事情进行了研究,但我在这里被难住了。

我是编码新手,尤其是二维数组。

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



int checkdiag(int size, int matrix[][size])
{
    int i,sum=0,verif;
    for(i=0;i<size;i++)
    {
       sum += matrix[i][i];
    }
    if(matrix[0][0]==((double)sum/(double)size))
        verif=1;
    else
        verif=0;


   return (verif);
}

int main()
{
    FILE *filename;
    char inputfile[25];
    int howmany,confirmdiag;
    int i,j; //Counter varibles
    int **matrix; // points to the first cell of 2d array [0][0]


    /* Type in exact file to open */
    printf("Please type in the exact name of the data file you with to use and please make  sure it is within the program folder.\nFor example: \"matrix1.txt\"\n");
    gets(inputfile);
    filename = fopen(inputfile,"r");

    if (filename==NULL)
    {
        system("cls");
        printf("\nCould not find the file you've requested, please make sure the file is on the   same partition.\n\n");
        getch();
        exit(0);
    }

    fscanf(filename,"%d",&howmany); //Scanning file to find size of the matrix

    matrix =(int **) calloc(howmany,sizeof(int*)); //Allocating memory for the ROWS of the matrix which are pointers of size (int*)

    for (i=0; i<howmany; i++)
    {
        matrix[i] =(int *) calloc(howmany,sizeof(int));//Allocating memory for the COLUMNS of the matrix which are integers of size (int)
    }

    for(i=0;i<howmany;i++)
    {
        for(j=0;j<howmany;j++)
        {
          fscanf(filename,"%d",&matrix[i][j]);//Scanning the file to fill the matrix array.
        }
    }

    confirmdiag=checkdiag(howmany, **matrix);

    if (confirmdiag==1)
    {
        printf("The matrix is %dx%d and all the numbers on the main diagonal are the same.",howmany,howmany);
    }
    else if (confirmdiag==0)
    {
        printf("The matrix is %dx%d. All the numbers on the main diagonal are not the same.",howmany,howmany);
    }

    for (i=0; i<howmany; i++)
        free (matrix[i]);

    free(matrix);

    return 0;
}

【问题讨论】:

  • 它究竟是从哪里开始崩溃的?你用调试器找出来了吗?
  • @DarkRiot43 我不明白。您是否需要检查主对角线上的所有元素是否彼此相等?
  • 失败的错误是什么?它在哪里出错(行号)?您是否尝试过附加调试器并单步执行代码?您是否尝试过打印出变量的值(printf 调试)?
  • @VladfromMoscow 是的,它们应该都是同一个数字。
  • @ha9u63ar 调用该函数时似乎崩溃了。我试过用 gbd.exe 调试,没有任何结果。

标签: c arrays function


【解决方案1】:

看起来不错。只是一个快速的提醒: 在您的函数调用中: **matrix 仅将矩阵 matrix(0,0) 的第一个元素发送到函数,因为您取消引用第一列的第一个条目。您需要发送一个指向指针的指针。试试:

confirmdiag=checkdiag(matrix, howmany, howmany);

对于方法定义:

int checkdiag(int** matrix, int sizeCol, int sizeRow)
{
...
}

祝你好运!

【讨论】:

  • 非常感谢!这就是为我解决的问题。对这些东西还是有点陌生​​,双重指向让我陷入了一个循环。你知道关于这个话题的解释有什么好的来源吗?干杯-皮埃尔
  • NP!我发现以下链接很有用:tutorialspoint.com/cplusplus/cpp_pointers.htm 和以下视频的指针部分 mycodeschool.com/videos 祝你好运!
【解决方案2】:

改变 confirmdiag=checkdiag(howmany, **matrix);confirmdiag=checkdiag(howmany, matrix); 因为没有理由取消引用指针。

【讨论】:

    【解决方案3】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    
    int checkdiag(int size, int matrix[][size]){
        int i, v=matrix[0][0];
    
        for(i=0;i<size;i++){
            if(v != matrix[i][i] || v != matrix[i][size-1-i])
                return 0;
        }
    
       return 1;
    }
    
    int main(void){
        FILE *file;
        char filename[25];
    
        printf("Please type in the exact name of the data file you with to use and please make sure it is within the program folder.\nFor example: \"matrix1.txt\"\n");
        scanf("%[^\n]%*c", filename);
    
        if ((file = fopen(filename, "r")) == NULL){
            system("cls");
            printf("Could not find the file you've requested, please make sure the file is on the same partition.\n\n");
            getch();
            exit(EXIT_FAILURE);
        }
    
        int howmany;
        fscanf(file, "%d", &howmany);
    
        int (*matrix)[howmany] = malloc(howmany * sizeof(*matrix));
    
        for(int i=0;i<howmany;i++)
            for(int j=0;j<howmany;j++){
              fscanf(file, "%d", &matrix[i][j]);
    
        if (checkdiag(howmany, matrix))
            printf("The matrix is %dx%d and all the numbers on the main diagonal are the same.",howmany,howmany);
        else
            printf("The matrix is %dx%d. All the numbers on the main diagonal are not the same.",howmany,howmany);
    
        free(matrix);
    
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      虽然您的方法可靠,但您还应该进行一些额外的初始化和验证。您选择calloc 进行分配非常好。它将元素分配/初始化到0 并防止任何尝试从未初始化的值中读取值。但是,在继续代码之前,您需要检查它是否成功。

      这同样适用于howmany。在通过代码分配和收费之前,需要简单检查它是valid number &gt; 0

      当您释放分配给matrix 的内存时,由于未能关闭file(将有500-600 字节与打开的文件描述符相关联),您可能会面临内存泄漏。

      fscanf 适用于从文件中读取整数值,但除非您知道并且可以保证输入文件的内容,请使用 line-input 命令,如 fgetsgetline,然后解析该行因为您需要的数字是一种更灵活的获取输入的方式。这只是你前进时要记住的事情。代码中的一个杂散字符将导致matching failurefscanf。 (还应检查fscanf 的返回,以确保您使用有效值完全填充矩阵——下面省略)

      最后,提示用户输入文件名并没有错,但一般来说,一段代码应该对传递给它的参数进行操作。使用int argc, char **argv 不仅可以轻松将您的测试代码稍后作为函数移动到您的代码主体中,等等。它还可以避免在测试:p 期间一遍又一遍地重新输入您的输入。

      将所有这些放在一起,并窃取 Bluepixy 的对角线检查,这是您代码的更新版本。仔细阅读,如果您有任何问题,请告诉我。 (注意您可以根据需要添加 getchconio.h,但应避免使用它们,因为它们不能移植到 Windows 之外)还包括一个快速打印例程,用于将矩阵打印到 @987654338 @你可能会觉得有用。

      #include <stdio.h>
      #include <stdlib.h>
      
      int checkdiag (int size, int **matrix);
      void prn_mtrx (int m, int n, int **matrix);
      
      int main (int argc, char **argv)
      {
          if (argc < 2) {
              fprintf (stderr, "error: insufficient input. Usage: %s filename\n", argv[0]);
              return 1;
          }
      
          FILE *file = NULL;
          char *filename = argv[1];
          int howmany = 0;
          int **matrix = NULL;
          int i = 0;
          int j = 0;
      
          /* open file & validate */
          if (!(file = fopen (filename, "r"))) {
              fprintf (stderr, "error: file open failed '%s'.\n\n", filename);
              exit (EXIT_FAILURE);
          }
      
          /* read / validate howmany value */
          if (!fscanf (file, "%d", &howmany) && howmany > 0) {
              fprintf (stderr, "error: invalid howmany value. (size not number > 0)\n\n");
              fclose (file);
              exit (EXIT_FAILURE);
          }
      
          /* allocate memory for matrix, initialize elements to '0' with calloc */
          if (!(matrix = calloc (howmany, sizeof *matrix))) {
              fprintf (stderr, "error: memory allocation failed '%s'.\n\n", filename);
              exit (EXIT_FAILURE);
          }
      
          for (i = 0; i < howmany; i++)
              if (!(matrix[i] = calloc (howmany, sizeof **matrix))) {
              fprintf (stderr, "error: memory allocation failed '%s'.\n\n", filename);
              exit (EXIT_FAILURE);
          }
      
          /* read values from file (preferably with fgets/getline, then parse tokens) */
          for (i = 0; i < howmany; i++)
              for (j = 0; j < howmany; j++)
                  fscanf (file, "%d", &matrix[i][j]);
      
          /* print the matrix */
          printf ("\nThe %dx%d matrix is:\n\n", howmany, howmany);
          prn_mtrx (howmany, howmany, matrix);
      
          /* check the diagonal */
          if (checkdiag (howmany, matrix))
              printf ("\nThe numbers on the main diagonal are the same.\n\n");
          else
              printf ("\nThe numbers on the main diagonal are NOT the same.\n\n");
      
          /* close file / free memory allocated to file */
          if (file) fclose (file);
      
          /* free memory allocated to matrix */
          for (i = 0; i < howmany; i++)
              free (matrix[i]);
          free (matrix);
      
          return 0;
      }
      
      /* check values on matrix diagonal */
      int checkdiag (int size, int **matrix)
      {
          int i, v = matrix[0][0];
      
          for (i = 0; i < size; i++) {
              if (v != matrix[i][i] || v != matrix[i][size - 1 - i])
                  return 0;
          }
      
          return 1;
      }
      
      /* print a (m x n) matrix (with pad) */
      void prn_mtrx (int m, int n, int **matrix)
      {
          register int i, j;
      
          for (i = 0; i < m; i++)
          {
              char *pad = " [ ";
              for (j = 0; j < n; j++)
              {
                  printf ("%s%3d", pad, matrix [i][j]);
                  pad = ", ";
              }
              printf ("%s", " ]\n");
          }
      }
      

      输出

      $ ./bin/matrix_diagonal dat/matrix_5.txt
      
      The 5x5 matrix is:
      
       [   1,   2,   3,   4,   5 ]
       [   6,   7,   8,   9,  10 ]
       [  11,  12,  13,  14,  15 ]
       [  16,  17,  18,  19,  20 ]
       [  21,  22,  23,  24,  25 ]
      
      The numbers on the main diagonal are NOT the same.
      

      【讨论】:

      • 很高兴我能帮上忙。在我之前这里有很多聪明的人伸出援助之手。我很高兴能够提供一个回馈。祝 C 好运,值得努力学习。
      猜你喜欢
      • 1970-01-01
      • 2017-08-28
      • 2015-06-03
      • 2011-01-18
      • 2012-06-27
      • 1970-01-01
      • 2014-04-18
      • 2012-11-23
      • 2015-03-06
      相关资源
      最近更新 更多