1

I'm trying to write a function that reads in a line from a file using fgets(). After reading the line, I want to take the line apart and make it into smaller strings. Depending on the first word in the line, the line that I read in can have 3-5 smaller strings that are separated by a white space.

Example: Line: remove apple 12345 string1: remove string2: apple string3: 12345

Line: add tomato red leaf string1: add string2: tomato string3: red string4: leaf

From the example above, if 1st string is remove, I need to read 2 other strings (apple, 12345). If the first string is add, I need to read 3 other strings (tomato, red, leaf).

Is there anyway that I can decide the number of times to read and do this using sscanf?

while( fgets( buf, sizeof buf, course_file ) != NULL ){
    sscanf( buf, "%s", &string1);
    printf( "%s\n", buf );
} 

It is not compulsory that I use sscanf, I'm open to other suggestions.

2
  • I'm unclear what you mean by "decide the number of times to read". Commented Sep 30, 2012 at 2:49
  • Sorry about that. Let's make it a precise example. If the first word is remove, I need to create 3 tokens(remove, apple, 12345) and if the first word is add, I need to create 4 tokens(add, tomato, red, leaf). Commented Sep 30, 2012 at 2:56

1 Answer 1

2

The function typically used to tokenize strings is strtok, but it is not thread-safe; its modern version is strtok_r should be used instead.

Start tokenizing the buf in the first call, check the first token, and then go into one of several loops that depend on the content of the first token:

while( fgets( buf, sizeof buf, course_file ) != NULL ) {
    char *saveptr;
    char *tok = strtok_r(buf, " ", &saveptr);
    if (!strcmp(tok, "delete")) {
        for (int i = 0 ; i != 3 ; i++) {
            tok = strtok_r(NULL, " ", &saveptr);
            // Do something with the token...
        }
    } else if (!strcmp(tok, "add")) {
        for (int i = 0 ; i != 4 ; i++) {
            tok = strtok_r(NULL, " ", &saveptr);
            // Do something else with the token...
        }
    } else {
        // Error
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Is there anyway that I can peek ahead to know if I really read in all the argument/mini-strings? I'm worried cause I'm required to handle a name field which could be any combination of first, middle and last name.
@user1043625 You can make your tokenizing logic to continue or stop based on the current token that you see. I mean, instead of a for loop you can use a while, or break out of the loop if you find a certain token or when the stream of tokens ends early.
Hmm, alright. Was wondering if there is a way for me to extract the pointer to current location of strtok_r.
@user1043625 There's a little problem with that, because strtok_r not only goes through the string, but also temporarily inserts terminating zeros into the original string at the next terminator. That's why going back on strtok_r is not easy.
I guess a while loop would do the job then. Thanks! :D

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.