2

I am parsing a file for particular keyword matching by C program, here is my sample code...

#include <stdio.h>

int main() { 

    FILE *infile = fopen("Somefile.txt", "r");

    char buffer[256];
    char value[128];

    while (fgets(buffer, sizeof(buffer), infile))
        if (1 == sscanf(buffer, " x = %s", value))
            printf("Value = %s\n", value);
    return 0;
}

Somefile.txt

some junk
#a comment
a = 1 ; a couple other variables.
b = 2
x = 3
 x = 4
x=5
x = Hi hello

Output:

Value = 3
Value = 4
Value = 5
Value = Hi

Problem : when x contain the value like "Hi Hello", then it just parsing "Hi" only, I want to parse whole value of x without loosing space.

please suggest me solution for it.

Thanks.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
Nimit
  • 1,714
  • 3
  • 22
  • 33
  • Standard C has no function really designed for what you want. But almost every compiler vendor provides a function that *does* do what you want. Alternately, read the file and do the format parsing yourself. – Billy ONeal Mar 21 '12 at 05:04
  • http://stackoverflow.com/questions/6853789/how-do-i-scan-spaces-into-a-a-string – vrdhn Mar 21 '12 at 05:25

2 Answers2

2

In this line of your code:

if (1 == sscanf(buffer, " x = %s", value))

%s means to read in one word.

If you want to read in the rest of the line, use %[^\n]s like this:

if (1 == sscanf(buffer, " x = %[^\n]s", value))
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
lnafziger
  • 25,760
  • 8
  • 60
  • 101
  • well, yeah, but that's ONLY going to match the 'x =' line. – Charlie Martin Mar 21 '12 at 05:11
  • Umm, it is the exact code that @nimit already had and the only problem that he had with it was that it didn't read the entire line. This will fix that. – lnafziger Mar 21 '12 at 05:14
  • And for that matter, if you read the question (and the examples given) he only wants the x lines. – lnafziger Mar 21 '12 at 05:16
  • Yeah, someone gave me -1 because they thought that you wanted more than the x lines... What was the result when you tried this? It should read to the end of the line. – lnafziger Mar 21 '12 at 05:19
  • @lnafziger: your answer is useful. I got the proper result. Thanks a lot. – Nimit Mar 21 '12 at 05:29
  • I don't get the `"%[^\n]s"` of the `sscanf()` format string. The `'s'` character will never match the `'\n'` character that's left in the stream (or string) after the `"%[^\n]"` is processed. I think it would be better to use `"%[^\n]%*c"` so the `'\n'` is discarded. It's not critical for `sscanf()` since no input state is maintained to the next call, but if this were an `fscanf()` or `scanf()`, the newline wouldn't be dealt with properly using `"%[^\n]s"`. I see this idea of putting an `'s'` after the `"%[scanset]"` specifier other places on the net - where does it come from? – Michael Burr Mar 21 '12 at 05:52
  • Actually I was incorrect. This is actually in the C standard, at least the latest versions. http://stackoverflow.com/a/6854000/82320 (See 7.19.6.2 ) – Billy ONeal Mar 21 '12 at 20:43
0

The first thing to do is back off on sscanf. If you read the man page, scanf treats spaces as specifications that say "you'll have some white space here, it's not important." Then other characters are specifications for literals. The effect is that that format spec is something like "any amount of while space, then an x, then more white space, then an '=', then more white space, then a string, and now return the string."

What you're really trying to do here is some lightweight parsing. You'll probably do better to read each line and scan it with a simple finite state machine, ie,

while not end of file
   while not end of line
      get next character
      if char == ";" -- comment
         break
      if char is a letter
         parse an assignment

and so on.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263