0

I just start learning C(optional school course). I stuck on a small problem for 2 days. So the basic idea is, I have bunch of data in a file that I want to extract. However, there are 2 formats that the data has, and the first letter on each line determines what action I need to take.

For example, the data in file looks like these:

S:John,engineer,male,30
S:Alice,teacher,female,40
C:Ford Focus,4-door,25000
C:Chevy Corvette,sports,56000
S:Anna,police,female,36

What I want to do is, after open the file, read each line. If the first letter is S, then use
fscanf(fp, "%*c:%[^,],%[^,],%[^,],%d%*c",name,job,sex,&age)
to store all variable so I can pass them to function people().

But if the first letter is C, then use
fscanf(fp, "%*c:%[^,],%[^,],%d%*c",car,type,&price)
to store so I can pass them to function vehicle().

Would really appreciated if anyone can give me some pointer on how to do this. Thanks.

2 Answers 2

1

There are many approaches, but separating IO from parsing is a good first step.

With line oriented data, it is so much cleaner to simply

FILE *inf = ...;
char buf[100];
if (fgets(buf, sizeof buf, inf) == NULL) Handle_EOForIOError();

Then parse it.

char name[sizeof buf];
char job[sizeof buf]; 
char sex[sizeof buf]; 
unsigned age;
char car[sizeof buf]; 
char type[sizeof buf]; 
unsigned cost; 
int n;

if (sscanf(buf, "S:%[^,],%[^,],%[^,],%u %n", name, job, sex, &age, &n) == 4 && 
    buf[n] == '\0') 
  Good_SRecord();
else if (sscanf(buf, "C:%[^,],%[^,],%u %n", car, type, &cost &n) == 3 && 
     buf[n] == '\0')  
  Good_CRecord();
else Garbage();

The " %n" trick is really good at making sure all the data parsed as expected without extra junk.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is the rough idea: parse the string in 2 steps:

"%c:%s"

will get you the first character and the rest of the string. Then, based on what you read in the first character, you can continue parsing the remaining part as

"%[^,],%[^,],%[^,],%d%c"

or

"%c:%[^,],%[^,],%d%c"

5 Comments

oh, I just saw the %*c part on my lecture notes and I assume it suppose to be there whenever I'm using %[^ ] to scan for string. Must be my teacher's habbit. Will try to use it with your method and report back!
* indicates that you are not going to assign the result of that format specifier, ie throw the element away. It is not useful if you use the technique I propose. On the other hand, it would allow you to scan the unmodified input string for both steps instead of first chopping it in 2 parts, which would allow you to have 1 less intermediate variable.
Well, I put the concept to a smaller test program and it works. Just gonna pop it into my main program now. Thanks so much!
Glad to hear that! Good luck with your course - and if there aren't any better answers that appear in say the next 24 hours, may I ask that you accept this answer? That way future visitors know that the proposed solution actually works.
Works great on the main program with some modification(I used "%c:%[^\n]" instead of "%c:%s"). Answer accepted! Thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.