Hello everybody.
I have to make "an-OCR-like" programm in C - it gets for example this to stdin:
*** *** ***
* * * * * * *
* * * * * * *
* * * * * * *
*** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** ***
and it must recognize the numbers. The complication is, that there can be also question marks ('?'):
*** *** ????? ***
? * ????? * * *
? * ???? * * *
? * ????? * * *
*** *** *** ??*??
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
If the number(s) can be uniquely determined, it prints them into stdout (in this case 8338), in the opposite case, it returns '?' instead of the number. If the number can't be identified, it returns X. The "display" has 9 rows, length is not specified. Numbers on the "display" are separated by a single column of gaps.
If the input is invalid (less than 9 rows, each row has different length, numbers aren't divided by a gap, input contains other characters than ' ', '*' and '?', it prints "Nespravny vstup" (it means "invalid input").
My code is:
/*
* File: main.c
* Author: Honza
*
* Created on 31. prosinec 2009, 16:11
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 20000
/*
*
*/
int getNum (char *rows[], int n) {
char num[46];
char mask[10][46] = {" *** * ** ** * * ** ** * *** ", " * * * * * * ", " *** * * * *** * * * *** ", " *** * * * *** * * * *** ", " * ** ** * *** * * * ", " *** * * * *** * * * *** ", " *** * * * *** * ** ** * *** ", " *** * * * * * * ", " *** * ** ** * *** * ** ** * *** ", " *** * ** ** * *** * * * *** "};
int i, j, c=0, match = 1, number = 11, recognized = 0;
// Get the number
for (i = 0; i < 9; i++) {
for (j = 0; j < 5; j++, c++) {
num[c] = rows[i][j+(n-1)*6];
}
}
num[46] = '\0';
// What number are you?
for (i = 0; i < 10; i++) {
for (j = 0; j < 45; j++) {
if (num[j] != mask[i][j]) {
if (num[j] != '?') {
match = 0;
break;
}
}
}
if (match == 1) {
if (number == 11) {
number = i;
recognized = 1;
}
else {
printf("?");
number = 12;
break;
}
}
match = 1;
}
if (recognized == 0) printf("X");
else if (number != 12) printf("%d", number);
return(0);
}
int main(int argc, char** argv) {
int i=1, j=0, n, len, length;
char** rows;
char str_buf[MAX_LEN];
// Get the length of the first line and store it into memory
fgets(str_buf, MAX_LEN, stdin);
len = strlen(str_buf);
rows = (char**)malloc(9 * sizeof(char*));
rows[0] = (char*)malloc((len-1) * sizeof(char));
strcpy(rows[0], str_buf);
// Get all the remaining lines
while (fgets(str_buf, MAX_LEN, stdin) != NULL && i<9) {
rows[i] = (char*)malloc((len-1) * sizeof(char));
strcpy(rows[i], str_buf);
i++;
}
// Where there enough lines?
if (i < 8) {
printf("Nespravny vstup.\n");
for (j = 0; j < i; j++) {
free(rows[j]);
}
free(rows);
return(0);
}
// If you find a line, which has a different length than others, quit
for (i = 1; i < 8; i++) {
length = strlen(rows[i]);
if (length != len) {
printf("Nespravny vstup.\n");
for (j = 0; j <= 8; j++) {
free(rows[j]);
}
free(rows);
return(0);
}
}
// Check for disallowed characters and missing spaces between numbers
for (i = 0; i < 9; i++) {
for (j = 0; j < len-3; j++) {
if (rows[i][j]!=' ' && rows[i][j]!='*' && rows[i][j]!='?') {
printf("Nespravny vstup.\n");
for (n=0; n<9; n++) {
free(rows[n]);
}
free(rows);
return(0);
}
if ((j+1)%6==0 && rows[i][j]!=' ' && (j+1)<(len-3)) {
printf("Nespravny vstup.\n");
for (i = 0; i < 9; i++) {
free(rows[i]);
}
free(rows);
return(0);
}
}
}
// Get the numbers
for (i = 1; i<= len/6; i++) {
getNum(rows,i);
}
printf("\n");
// Clean up
for (i = 0; i < 9; i++) {
free(rows[i]);
}
free(rows);
return (EXIT_SUCCESS);
}
The sample data are (first 9 rows are input, last line is a required output) following (11 in total):
*** *** ***
* * * * * * *
* * * * * * *
* * * * * * *
*** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** ***
01234
*** *** *** *** ***
* * * * * * *
* * * * * * *
* * * * * * *
*** *** *** ***
* * * * * * *
* * * * * * *
* * * * * * *
*** *** *** ***
98765
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
8338
*** *** ????? ***
? * ????? * * *
? * ???? * * *
? * ????? * * *
*** *** *** ??*??
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
8338
*** *** *** ***
????? * ? * * *
????? * ? * * *
????? * ? * * *
*** ??? *** ***
* * * ? * ? *
* * * ? * ? *
* * * ? * ? *
*** ??? *** ***
????
*** *** *** ***
* * * * * *
* * * ? *
* * * ? * *
*** *** *** ***
* ? * ? * *
* * * ? * *
* ? * ? * ? *
*** *** *** ***
XX?X
*** *** *** ***
* * * ** *
* * * ** *
* * * ** *
*** *** *** ***
* * * ** *
* * * ** *
* * * ** *
*** *** *** ***
Nespravny vstup.
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
Nespravny vstup.
*** *** *** ***
* * * *x* *
* * * * * *
* * * * * *
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
Nespravny vstup.
*** *** *** ***
* * * x * *
* * * x * *
* * * x * *
*** *** *** ***
* * * * * *
* * * * * *
* * * * * *
*** *** *** ***
Nespravny vstup.
***
* *
Nespravny vstup.
My programm works for 7 of 11 (I don't know which ones). In all cases it returns required output, so I guess I forgot to deallocate some memory or something.
I'm really desperate and I would very appreciate your help.