0

I'm trying to read a text file containing integers via stdin and store the values in a 9x9 array (please note that the file must be read via stdin and not as an arg)

This is what I have:

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


int main()
{
    int puzzle[9][9];
    int i,j,count=0;  
    char value[81];

    for( i = 0; i < 9; i++ ) {  
      for( j = 0; j < 9; j++ ) {  
        scanf("%c", &value[count]);  
        puzzle[i][j] = value[count] - '0'; 
        count++;  
      }
    }
}

But it doesn't seem to convert the ASCII characters from scanf to int, which is what I thought the value[count] - '0' was supposed to do, so I end up getting values like this:

-16-16-160-16-160-16-161

Basically i'm trying to do exactly whats described in this thread, but in C instead of C++:

How to convert a 2d char array to a 2d int array?

Edit -

The input file looks like this (contains both white space and new lines):

   0  0  1  9  0  0  0  0  8         
   6  0  0  0  8  5  0  3  0     
   0  0  7  0  6  0  1  0  0     
   0  3  4  0  9  0  0  0  0     
   0  0  0  5  0  4  0  0  0     
   0  0  0  0  1  0  4  2  0     
   0  0  5  0  7  0  9  0  0
   0  1  0  8  6  0  0  0  7
   7  0  0  0  0  9  2  0  0        
Community
  • 1
  • 1
Martin
  • 1,060
  • 2
  • 16
  • 28
  • 5
    The `%c` conversion doesn't skip initial whitespace. Use `scanf(" %c", &value[count]);` while I look for a duplicate. – Daniel Fischer May 18 '13 at 12:33
  • 3
    @DanielFischer *"while I look for a duplicate."*. lol – Maroun May 18 '13 at 12:34
  • Exactly. -16 is code of whitespace (32) minus code of zero (48). By the way, your input contains integers (as a separate number) and you are reading digits (as single characters). Why? – nullptr May 18 '13 at 12:34
  • 2
    If the text file contains integers and You don't need for the value array, You can directly scanf them with %d into the puzzle array –  May 18 '13 at 12:35
  • 1
    possible duplicate of [scanf not taking in data](http://stackoverflow.com/questions/4129413/scanf-not-taking-in-data) – Daniel Fischer May 18 '13 at 12:55
  • @DanielFischer so you were really looking. lol again. – Maroun May 18 '13 at 13:11
  • 1
    @MarounMaroun Otherwise, I would have answered the question. Would have been faster, and could have earned an upvote or two. – Daniel Fischer May 18 '13 at 13:16

3 Answers3

2

The problem is not with the conversion line puzzle[i][j] = value[count] - '0';. The problem lies with the following scanf() statement, scanf("%c", &value[count]);. The scanf is reading the first white space. Use scanf(" %c", &value[count]); to read the input.

Deepu
  • 7,592
  • 4
  • 25
  • 47
2

%c does eactly what it should: it reads one character. D'oh, it's whitespace? That doesn't matter. This is why...

  • ... you shouldn't use %c but %d for scanning integers;

  • ...you shouldn't use scanf() at all for something simple like this.

What I'd do if I were you:

int matrix[9][9];
int i = 0;

char buf[0x100];
while (fgets(buf, sizeof(buf), stdin)) {
    char *end;
    char *p = strtok_r(buf, " ", &end);
    while (p) {
        matrix[i / 9][i % 9] = strtol(p, NULL, 10);
        i++;
        p = strtok_r(NULL, " ", &end);
    }
}
0

Is there any reason this doesn't work? Scan them in as integers.

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


int main()
{
    int puzzle[9][9];
    int i,j,count=0;  
    char value[81];

    for( i = 0; i < 9; i++ ) {  
      for( j = 0; j < 9; j++ ) {  
        scanf("%d", &value[count]);  
        puzzle[i][j] = value[count];
        printf("%d", puzzle[i][j]); //to verify it is stored correctly
        count++;  
      }
    }
}

EDIT: since you said it's coming from a file, i copy/pasted the sample file you gave into C:\file.txt, and the following code appears to work just dandy.

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


int main()
{
    FILE *fp;
    int puzzle[9][9];
    int i,j,count=0;  
    int value[81];
    fp = fopen("C:\\file.txt", "r");
    for( i = 0; i < 9; i++ ) {  
      for( j = 0; j < 9; j++ ) {
        fscanf(fp, " %d", &value[count]);
        puzzle[i][j] = value[count];
        printf("element %d is %d\n",count,  puzzle[i][j]);
        count++;

      }
    }
}
Tadgh
  • 1,999
  • 10
  • 23
  • It gives a warning `format ‘%d’ expects type ‘int *’, but argument 2 has type ‘char *’`, but still runs. Strangely, it doesn't seem to scan some digits properly too. – Martin May 18 '13 at 12:53
  • Should directly scan into `puzzle`, `scanf(%d", &puzzle[i][j]);`. – Daniel Fischer May 18 '13 at 12:56
  • You are quite right. The intermediate value array is apparently unnecessary, unless the author has some other purpose for it – Tadgh May 18 '13 at 13:07