【问题标题】:How to convert a 2D char array to a 2D int in c如何在 c 中将 2D char 数组转换为 2D int
【发布时间】:2016-12-08 15:09:42
【问题描述】:

我正在编写一个程序,它接收一个使用 A-I 而不是 1-9 的数独板并检查该板是否有效。 我从文件中读取了数独板,并使用开关将所有值更改为数字。

我的计划是使用 atoisscanf 将 2D char 数组转换为 2D int 数组,以便我可以添加所有行和列来检查它是否是有效的板。但是,当使用这些功能时,我会收到警告:

预期类型为 const char 但参数是 char 类型或传递参数 sscanf 之一使指针从整数而不进行强制转换。

我对指针仍然很困惑,所以我不知道这到底意味着什么。是否有可能将我的 2d char 数组更改为 2d int 数组,如果有的话有什么建议吗?如果有更好的方法来检查董事会是否有效建议也将不胜感激。谢谢

int main() {
  int i, j;
  char **matsudoku = malloc(9*sizeof(char*));
  for (i=0; i<9; ++i)
    matsudoku[i]=malloc(9*sizeof(char));

  FILE *fpointer = fopen("C:/Users/Owner/Documents/Como Sci in C/sudokuchar.txt", "r");

  if (fpointer == NULL) {
    printf("Cannot open file \n");
    exit(0);
  }

  for(i=0; i<9; i++){
    for(j=0; j<9; j++){
       fscanf(fpointer, " %c", &matsudoku[i][j]);
       switch (matsudoku[i][j]){
           case 'A':
              matsudoku[i][j]='1';
              break;
           case 'B':
              matsudoku[i][j]='2';
              break;
           case 'C':
              matsudoku[i][j]='3';
              break;
           case 'D':
              matsudoku[i][j]='4';
              break;
           case 'E':
              matsudoku[i][j]='5';
              break;
           case 'F':
              matsudoku[i][j]='6';
              break;
           case 'G':
              matsudoku[i][j]='7';
              break;
           case 'H':
              matsudoku[i][j]='8';
              break;
           case 'I':
              matsudoku[i][j]='9';
              break;
         }
        printf("%c",matsudoku[i][j]);
    }

}
//atoi(matsudoku);
int k;
//or sscanf(matsudoku,"%d",%k);
fclose(fpointer);
}

【问题讨论】:

  • 为什么不直接使用int 的二维数组并读入呢?
  • @ameyCU 所以当我从文件中读取时,我如何将 A 到 I 字符直接更改为 1-9??
  • @samgak 嗯,这两种方法都不适合我,会导致奇怪的符号代替字母
  • C 保证字符是算术类型 09保证是连续的,所以'0' - '0' == 0,和'9' - '0' == 9,因此将数字字符转换为整数可以通过减去字符'0'或使用atoi来完成

标签: c char int scanf atoi


【解决方案1】:

我更喜欢这种没有 atoi 或 switch/case 的方法,而是非常直接地利用了 ASCII 表的性质。只需读入一个字符,然后减去“A”。所以如果字符是'A',那么'A' - 'A' 是0。但你的意思是这个是“1”,因此,你在这里加1。

  int main() {
      int i, j;
      char nextchar;
      int **matsudoku = malloc(9*sizeof(int*));
      for (i=0; i<9; ++i)
        matsudoku[i]=malloc(9*sizeof(int));

      FILE *fpointer = fopen("C:/Users/Owner/Documents/Como Sci in C/sudokuchar.txt", "r");

      if (fpointer == NULL) {
        printf("Cannot open file \n");
        exit(0);
      }

      for(i=0; i<9; i++){
        for(j=0; j<9; j++){
          fscanf(fpointer, " %c", &nextchar);
          matsodoku[i][j] = (int)(nextchar-'A') + 1;
          printf("%d",matsudoku[i][j]);
      }

    }
    fclose(fpointer);
 }

【讨论】:

  • 行:matsodoku[i][j]=(int)(c-'A')+1,什么是c?
  • 我也必须对每个字母都这样做,你这里的代码是否只将 A 转换为一个?对不起,我有点困惑
  • 此处的代码将文件中的任何字符转换为正确的数字
  • 'B' - 例如,'A' 为 1。所以你加另一个 1 得到 2。所以 A 是 1,B 是 2,依此类推。
【解决方案2】:

当您可以将值直接读取到int 的二维数组中时,确实没有理由使用 pointer-to-pointer-to-char。虽然有很多方法可以解决这个问题,但坚持您的方法,您可以简单地执行以下操作...将文件中的每个字符读取/验证为 tmp 值,然后分配给将执行字符转换的 matsudoku[i][j] = tmp - '0';一步到位。

把它放在一起,你可以做类似以下的事情:

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

#define SDKSZ 9

int main (void)
{
    int i, j;
    int matsudoku[SDKSZ][SDKSZ] = {{0}};

    FILE *fpointer =
        fopen ("C:/Users/Owner/Documents/Como Sci in C/sudokuchar.txt", "r");

    if (fpointer == NULL) {
        printf ("Cannot open file \n");
        exit (0);
    }

    for (i = 0; i < SDKSZ; i++)
        for (j = 0; j < SDKSZ; j++) {
            int tmp;
            if (fscanf(fpointer, " %d", &tmp) != 1) {   /* read/validate tmp */
                fprintf (stderr, "error: on read matsudoku[%d][%d]\n", i, j);
                exit (1);
            }
            matsudoku[i][j] = tmp - '0';  /* convert from ASCII to numeric */
        }
    fclose (fpointer);

    for (i = 0; i < SDKSZ; i++) {
        for (j = 0; j < SDKSZ; j++)
            printf (" %3d", matsudoku[i][j]);
        putchar ('\n');
    }

    return 0;
}

如果您有任何疑问或问题,请告诉我(我没有要测试的数据)。

【讨论】:

    【解决方案3】:

    我不会将字母字符转换为数字字符,而是创建一个新的 int 类型的二维数组:

    int matSudokuInt[9][9];
    for(i=0; i<9; i++)
    {
        for(j=0; j<9; j++)
        {
            fscanf(fpointer, " %c", &matsudoku[i][j]);
            switch (matsudoku[i][j])
            {
                case 'A':
                    matSudokuInt[i][j]=1;
                    break;
                case 'B':
                    matSudokuInt[i][j]=2;
                    break;
                case 'C':
                    matSudokuInt[i][j]=3;
                    break;
                case 'D':
                    matSudokuInt[i][j]=4;
                    break;
                case 'E':
                    matSudokuInt[i][j]=5;
                    break;
                case 'F':
                    matSudokuInt[i][j]=6;
                    break;
                case 'G':
                    matSudokuInt[i][j]=7;
                    break;
                case 'H':
                    matSudokuInt[i][j]=8;
                    break;
                case 'I':
                    matSudokuInt[i][j]=9;
                    break;
            }
            printf("%d ", matSudokuInt[i][j]);
        }
        printf("\n");
    }
    

    那么对行和列求和就变得容易了:

    int sum = 0;
    int rowSum[9];
    int colSum[9];
    // Let i be the column index and j be the row index
    for (j = 0; j < 9; j++) {
        sum = 0;
        for (i = 0; i < 9; i++) {
            sum += matSudokuInt[i][j];
        }
        rowSum[j] = sum;
    }
    
    for (i = 0; i < 9; i++) {
        sum = 0;
        for (j = 0; j < 9; j++) {
            sum += matSudokuInt[i][j];
        }
        colSum[i] = sum;
    }
    

    然后您可以轻松查看 sum 数组并检查所有条目是否相等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      相关资源
      最近更新 更多