I agree with qny's approach, except that I'd use a nested loop like this:
Code:
char linebuf[200]; /* Length of longest possible input line + 1 */
char *line;
int rows, cols, iterations;
double eps, err;
int row, col;
double value;
/* Loop over matrices: */
while (1) {
/* Read new line from standard input. */
line = fgets(linebuf, sizeof linebuf, stdin);
if (!line) {
/* No more input, no more matrices. */
break;
}
/* Parse matrix declaration. */
if (sscanf(line, "%d %d %d %lf %lf", &rows, &cols, &iterations, &eps, &err) < 5) {
/* Bad line. Remove newline at end of line. */
line[strcspn(line, "\r\n")] = '\0';
fprintf(stderr, "%s: Invalid matrix declaration.\n", line);
/* Break out of loop, just as if input had ended. */
break;
}
/*
* TODO: initialize a suitable matrix structure.
*/
/* Sparse matrix element loop. */
while (1) {
/* Read new line from standard input. */
line = fgets(linebuf, sizeof linebuf, stdin);
if (!line) {
fprintf(stderr, "Warning: Premature end of input while reading matrix elements.\n");
break;
}
/* Matrix element? */
if (sscanf(line, " %d %d %lf", &row, &col, &value) >= 3) {
/*
* TODO: Set matrix element at row 'row', column 'col' to 'value'
*/
} else
if (sscanf(line, " %d", &row) >= 1 && row == -1) {
/* End of matrix elements */
break;
} else {
/* Remove newline from the end of line. */
line[strcspn(line, "\r\n")] = '\0';
fprintf(stderr, "%s: Not a matrix element.\n", line);
/* Break out; treat the error as if it was a -1. */
break;
}
}
}
You could also add a flag you set before each break in the inner loop, and check it at the end of the outer loop, to differentiate between input format errors and normal operation.
If you wanted to add support for skipping empty lines (containing at most only white-space characters) and comment lines (lines beginning with a # or a ; ) all you need would be to add
Code:
/* Skip leading whitespace in the line. */
line += strspn(line, "\t\n\v\f\r ");
/* Skip comment lines and empty lines. */
if (*line == '#' || *line == ';' || *line == '\0')
continue;
after each if (!line) statement.