Reputation: 77
Can any one explain to me how to make a C program to read input from a file according to the following scenario:
12
2-4,7,9;
1,4,11-12;
1,4,10,12;
1,4-8,10-12;
1,8;
1,3-6,8,10-12;
1,3,5-6,8,11;
1,8,10-12;
1-8;
;
2;
2-4,7-10,12;
The first number (on the first line) describes what size the grid should be, in this case a 12x12 grid. The following lines describe how many cells are occupied on each row of the grid. For example, in the first row the cells from 2 to 4 and 7 and 9 are occupied; in the second row, the cells 1, 4 and from 11 to 12 are occupied and so on.
Right now I have this code, but it is not solving my problem ...
#include <stdio.h>
#include <stdlib.h>
void main()
{
char content[3000];
int value;
FILE *ptr_file = fopen("data.txt", "r");
if(!ptr_file)
return 1;
int j;
while(fgets(content, 3000, ptr_file)!=NULL){
printf("%s", content);
value = atoi(content);
for(j=0; j<3000; j++){
value = content[j];
printf("%i", value);
}
}
return 0;
}
Console throws just a bunch of random numbers ...
Upvotes: 1
Views: 114
Reputation: 40145
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
enum { EOD = -1, EOL = -2, ERR = -3, OFF = 0, ON = 1 };//End Of Data, End Of Line
int getValue(FILE *fp){
static int on_yield = OFF, prev, end;
if(on_yield == ON && prev < end){
return ++prev;
}
on_yield = OFF;
int n, ch = fgetc(fp);
if(ch == EOF)
return EOD;
else if(ch == ';')
return EOL;
else if(ch == ',' || ch == '\n')
return getValue(fp);//or change to using loop
else if(isdigit(ch)){
ungetc(ch, fp);
fscanf(fp, "%d", &n);
return prev=n;
} else if(ch == '-'){
on_yield = ON;
fscanf(fp, "%d", &n);
end = n;
return getValue(fp);
}
fprintf(stderr, "(%c) invalid format in file\n", ch);
return ERR;
}
int main(void){
FILE *ptr_file = fopen("data.txt", "r");
if(!ptr_file){
perror("fopen");
return 1;
}
int size;
fscanf(ptr_file, "%d", &size);//check omitted
char (*cell)[size] = malloc(size * sizeof(*cell));
memset(&cell[0][0], ' ', size*size);
int r = 0, c, value;
while((value=getValue(ptr_file))!=EOD){
if(value == EOL){
++r;
continue;
}
if(value > 0)
cell[r][value-1] = '*';
}
fclose(ptr_file);
for(r = 0; r < size; ++r){
for(c = 0; c < size; ++c){
putchar(cell[r][c]);
}
putchar('\n');
}
free(cell);
return 0;
}
Upvotes: 0
Reputation: 137
The "random" numbers are the byte values from your file and you forgot to stop at end of line. Dave's solution is not quite right for c. After read a line:
while not semicolon
strtoul a number
if no number
exit error
if next char is hyphen
shift to next char
strtoul end of range
if no number
exit error
set cells
else
set cell
if next char is not semicolon
shift to next char
You should not use atoi for anything ever. Use sscanf or strto….
Upvotes: 1
Reputation: 11975
Pseudo-code:
Open your file
Read the first line
Extract the value N
Allocate your grid
Loop N times
Read a line
If not an empty line, ie. semi-colon only
Split into tokens by comma
Check for a range or a single digit
Extract numbers
Set cells accordingly
Upvotes: 1