Eug G
Eug G

Reputation: 39

How to read lines with different formats

I have an input file with the following form

i 176064 Patterson Denise 8.58 11 DEN 15788 
q 188464
ra 148702 167443
a  73131
d 163464
f 6.00
ct 73131 PHY
b 3
p 15703
pe
m 144626 6.51 8
e

The first character in each line[i,q,ra,a...] represents an code to a function , while the rest are values that I must store into variables,depending on that code. What's the best way to achieve this ? I have been thinking about using fscanf but each line does not have a specific format, the format itself depends on the code [i,q,ra,a,b..]

Upvotes: 0

Views: 192

Answers (1)

chux
chux

Reputation: 153508

To read a line, use fgets()

char buffer[100];
while (fgets, buffer, sizeof buffer, istream) != NULL) {

Then scan the line against the various formats, each ending with " %n". "%n" records the scan position, if it got that far. Additional tests could check for extraneous extras character starting at n.

  int num1, num2, num3;
  char last[sizeof buf];
  char first[sizeof buf];
  char code[sizeof buf];
  double rate;
  int n = 0;
  //               v..v..v..v...v..v..v spaces optional here
  sscanf(buffer, "i %d %s %s %lf %d %s %d %n",
    &num1, last, first, &rate, &num2, code, &num3, &n);
  if (n) {
    Handle_i();
    continue;
  }
  sscanf(buffer, "q %d %n", &num1, &n);
  if (n) {
    Handle_q();
    continue;
  }
  sscanf(buffer, "ra %d %n", &num1, &num2, &n);
  if (n) {
    Handle_ra();
    continue;
  }
  sscanf(buffer, "e %n", &n);
  if (n) {
    Handle_e();
    continue;
  }
  ...
  fail();
}

As each format begins with a unique letter pattern, the sscanf() will quickly exit on mis-match.

Alternative, code could parse out the initial letters for a slightly more efficient decision tree. Suspect profiling will show little performance difference.

As with any complex format, consider how one would maintain the code and it is bound to evolve.

Upvotes: 1

Related Questions