简体   繁体   中英

How to convert a 2D char array to a 2D int in c

I am writing a program that takes in a sudoku board that uses AI instead of 1-9 and checks if the board is valid. I read the sudoku board from a file and i used the switch to change all values to numbers.

My plan was to use atoi or sscanf to convert the 2D char array to a 2D int array so that i can add all the rows and columns to check if it is a valid board. However when using these functions i get the warnings:

expected type const char but argument is of type char or passing argumet one of sscanf makes pointer from integer without cast.

I'm still quite confused on pointers so idk what this really means. is it even possible to change my 2d char array to a 2d int array, if so any suggestions? if there is a better way to check if the board is valid suggestions would be greatly appreciated as well. Thanks

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);
}

I prefer this method without an atoi or a switch/case but instead exploits the nature of the ASCII table very directly. Simply read in a character but then subtract 'A'. So if the character was an 'A', then 'A' - 'A' is 0. But you mean this to be the "1" and thus, you add 1 here.

  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);
 }

There is really no reason to use a pointer-to-pointer-to-char to begin with when you can read the values directly into a 2D array of int . While there are many ways to approach this, sticking with your approach, you could simply do the following... read/validate each character from your file into a tmp value and then assign to matsudoku[i][j] = tmp - '0'; which will perform the character conversion in one step.

Putting it together, you could do something similar to the following:

#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;
}

Let me know if you have any questions or problems (I didn't have data to test).

Instead of converting the letter characters to number characters, I'd make a new 2D array of type 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");
}

Then it becomes easy to sum the rows and columns:

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;
}

You can then easily look through the sum arrays and check that all entries are equal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM