katDouglas
katDouglas

Reputation: 11

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

Upvotes: 0

Views: 1153

Answers (3)

Shaun Ramsey
Shaun Ramsey

Reputation: 571

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

Upvotes: 2

David C. Rankin
David C. Rankin

Reputation: 84569

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).

Upvotes: 0

naffarn
naffarn

Reputation: 562

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.

Upvotes: -1

Related Questions