I need to create a program to read a file line by line and in each line scan some data. for example in a line like :
# 2 (x1,y1)(x2,y2)
i need x1,y1 and x2,y2 my code is
char firstCharacter;
char line[100];
scanf("%c",&firstCharacter);
while ((fgets(line, sizeof line, stdin) != NULL) && (line[0] != '\n')){
if(firstCharacter == '#'){
int nu_deadend;
sscanf(line,"%d",&nu_deadend);
for (int i = 0; i < nu_deadend; i++) {
int x,y;
sscanf(line,"(%d,%d)",&x,&y);
printf("x: %d y: %d\n",x,y);
}
}
}
return 0;
but from input:
# 2 (2,3)(3,4)
it outputs:
x:0 y:0
x:0 y:0
expected output:
x:2 y:3
x:3 y:4
what am I doing wrong?
From my top comment ...
Unlike scanf
which continues where it left off, sscanf
will start at the buffer it is given. So, you probably need to use (e.g.) char *cp = line;
and then use and advance cp
to point to the next token.
sscanf
is ill-suited to this because it returns a count and not the number of bytes consumed.
Better to use fgets
, cp
, and strtok
and pass the return value of strtok
to sscanf
Also, you never reset firstCharacter
for the second line (i.e. I presume each line starts with #
)
Here is a refactored version. It is annotated:
#include <stdio.h>
#include <string.h>
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
int
main(void)
{
char *tok;
char line[100];
// FORMAT:
// # <count> (x,y)(x,y)...
while (fgets(line, sizeof line, stdin) != NULL) {
dbgprt("LINE: %s",line);
// get first token
tok = strtok(line," \n");
if (tok == NULL)
break;
// this must be "#"
if (*tok != '#')
continue;
// get the count
int nu_deadend;
tok = strtok(NULL," \n");
sscanf(tok, "%d", &nu_deadend);
dbgprt("NUM: %d\n",nu_deadend);
// get "(x,y)(x,y)(x,y)"
tok = strtok(NULL," \n");
for (int i = 0; i < nu_deadend; i++) {
int x, y;
dbgprt("TOK: '%s'\n",tok);
sscanf(tok, "(%d,%d)", &x, &y);
printf("x: %d y: %d\n", x, y);
// advance past the end of the current (x,y)
tok = strchr(tok,')');
if (tok == NULL)
break;
++tok;
}
}
return 0;
}
Here is the test input I used:
# 2 (2,3)(3,4)
# 3 (1,7)(9,2)(8,3)
Here is the debug output:
LINE: # 2 (2,3)(3,4)
NUM: 2
TOK: '(2,3)(3,4)'
x: 2 y: 3
TOK: '(3,4)'
x: 3 y: 4
LINE: # 3 (1,7)(9,2)(8,3)
NUM: 3
TOK: '(1,7)(9,2)(8,3)'
x: 1 y: 7
TOK: '(9,2)(8,3)'
x: 9 y: 2
TOK: '(8,3)'
x: 8 y: 3
And, here is the clean output:
x: 2 y: 3
x: 3 y: 4
x: 1 y: 7
x: 9 y: 2
x: 8 y: 3