2

Sorry if this is fairly obvious but I haven't been able to find it anywhere. I'm writing a config file parser in c. the files will look something along the lines of

   PARAM1 VALUE1
   PARAM2 VALUE2 

etc. I'm using fscanf to read in the file and everything works smoothly but it needs to be able to toss out garbage such as random characters. It does this well unless the random characters have an uneven number f breaks (ie 3 words, such as "sdjsdh sddfi sifsi" or 1 word sch as "sjdasfh"). In which case it uses the param value from the next line down as a "value" related as the last word in the above line's "parameter". The code is smart enough to toss this out but then the next time fscanf gets called, it makes the first unused value the parameters, which should actually be a value(ie it thinks VALUE1 is the parameter and PARAM2 is the value). My fscanf command looks like this:

    fscanf(fp, "%s %s",temp_param, temp_value);

Where temp_value is the value and temp_param is the parameter.

The value's type is determined and then the parameter is checked against a list of allowed parameters like so:

   for(int y = 0; y< NUMBER_OF_PARAMS; y++){
        if (strcmp(temp_param, parameters[y])==0){
            found = 1;
            return y;

And then a strucutre where each variable is associated with a parameters[y] value is assigned:

    if (goodparam == 0){
            test->something= int_convert;
        }else if (goodparam == 1){
            test->anotherthing = int_convert;
        }else if (goodparam == 2){
            test->thing3 = int_convert;
        }else if (goodparam == 3){
            test->thingy = int_convert;
        }else if (goodparam == 4){
            strcpy(test->fakestring,temp_value);
        }else if (goodparam == 5){
            strcpy(test->otherstring,temp_value);

Is there a way I can get fscanf to stop in its tracks if it hits a newline character so this isn't screwed up?

Thanks

  • I think this question might have what you're looking for. https://stackoverflow.com/questions/861793/trouble-reading-a-line-using-fscanf If not, can you post a bit more code and perhaps I can find a way to implement a fix for you? Right now this is very limited. – J0hn Jun 30 '17 at 13:52
  • 2
    Don't write a parser using `fscanf`. Instead, read complete lines and use `sscanf`. – Sinan Ünür Jun 30 '17 at 13:52
  • What if there are *four* whitespace-delimited strings on a line? Does this constitute two separate name/value pairs? One pair plus garbage? One pair, with the value containing whitespace? – John Bollinger Jun 30 '17 at 13:52
  • 3
    The best way to get `fscanf` to behave the way you want is to use `fgets`! – William Pursell Jun 30 '17 at 13:52
  • @JohnBollinger yeah, it breaks it up into two different pairs and throws both away, then the code works normally – D. Jamieson Jun 30 '17 at 14:06
  • @WilliamPursell I previously was using fgets and sscanf, but my boss wanted me to use fscanf as it's more compact and we're working with an embedded system – D. Jamieson Jun 30 '17 at 14:07
  • @J0hn added code – D. Jamieson Jun 30 '17 at 14:14
  • `fscanf(fp, "%s", temp_param); if(!garbage(temp_param)){ fscanf(fp, "%s", temp_value); if(!garbage(tenp_value)) { /* Yay */ } }`? – Spikatrix Jun 30 '17 at 14:24
  • In general, `fscanf()` doesn't care about newlines (and it is hard work to make it care — very hard work). If you care about them, you need to do line-based input ([`fgets()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html) or POSIX [`getline()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html)) and then parse the data from the input line. You can spot missing fields and extra fields. You can probably use `sscanf()`; there are many other functions that could be used (`strcspn()`, `strpbrk()`, `strtok_r()` — to name but a few). – Jonathan Leffler Jun 30 '17 at 14:27
  • @CoolGuy Yeah, that worked. Can't believe I didn't think of that before – D. Jamieson Jun 30 '17 at 14:35
  • @D.Jamieson `fscanf(fp, "%s", temp_param);` will not "stop in its tracks if it hits a newline character". It will _first_ read newlines and more newlines, not saving them until it hits non-white-space text. Then is saves that text. _then_ it will stop when it scans a new-line or other white-space. – chux - Reinstate Monica Jun 30 '17 at 15:17
  • @D.Jamieson Specifiers other than `%n, %c, %[` all first consume newlines without any indication in the `fscanf()` result. To detect new-lines with `fscanf()` code needs to use `%c` or `%[`. IAC, `fgets()` is a better approach. – chux - Reinstate Monica Jun 30 '17 at 15:21
  • @chux you're right, however that solution solves my problem for all the cases I need it solved for – D. Jamieson Jun 30 '17 at 16:27

0 Answers0