Search code examples
cregexstrcmp

Detect quoted strings with fscanf


I want to read in C the content of a file like this:

foo="bar"
alice="bob"
fruit="pineapple"

And I am interested in the specific value associated with the key alice, but without the surrounding quotes. So, I want bob.

So, I've written something like this

EDIT: Added printf of key/value

char key[20];
char value[20];
char output[20];

memset(key, 0, 20);
memset(value, 0, 20);

while(fscanf(fd, "%19[^=]=\"%19[^\"]\"", key, value) != EOF) {

    printf("%s=%s", key, value);

    if (strcmp(key, "alice") == 0) {
      memset(output, 0, 20);
      strncpy(output, value, 20);
      break;
    }

    memset(key, 0, 20);
    memset(value, 0, 20);
}

The problem is the strcmp never returns 0. So, the comparation between any key and "alice" is always false. And I'm getting this output:

foo=bar
alice=bob
fruit=pinneaple
=pineapple

Also tested the length of each key, by strlen, and it's correct. Apart from the last line of rubish, I get what I expect. So, I don't really understand...

Is there any obvious error here? I'm trying to debug the code, but I'm working with a target system very limited (openwrt), and I don't have access to gdb (actually, the code is cross-compiled in another machine, because my target one doesn't even have a compiler).

Any help is appreciated.


Solution

  • Do not use scanf() for user input (even when it comes from a file). Prefer fgets().

    Your immediate problem is with whitespace.

    The contents of the file include '\n'. The '\n' are included in key.

    If you want to keep using fscanf() try adding some spaces inside the conversion string:

    while (fscanf(fd, " %19[^=]= \"%19[^\"]\"", key, value) == 2) /* ... */;
    //                 ^        ^ (2nd one isn't as important)
    

    Also notice I changed the condition. Rather than testing against EOF, test for a return value of 2.