16

I have fscanf to read lines of setting from a configuration file. Those settings have strictly predefined format which looks like

name1=option1;
name2=option2;
...

so basically I do

fscanf(configuration,"%[^=]=%[^;];",name,option);

where configuration is the file stream and name and option are programming buffers.

The problem is that the name buffer contains a newline character I don't want. Is there format specifier I've missed in the "[^...]" set to skip newline character? Anyway, can it be solved through format specifier ever?

BTW: Swallowing the newline character by writting this

"%[^=]=%[^;];\n"

is not elegent I think for that the newline character could repeat more than once anywhere.

Yang
  • 777
  • 1
  • 10
  • 19
  • 1
    If the `nameN` fields cannot contain whitespace, just add a space to the front of the format string - `" %[^=]=%[^;];"` - to skip leading whitespace. If they can, you need to consume the newline on its own with `getchar()`. – Daniel Fischer Nov 04 '12 at 19:11
  • 1
    The accepted answer is right, anyway, about repeated newlines you could use `%*[\n]` to read an arbitrary number of `'\n'` without storing them. – effeffe Nov 04 '12 at 19:59

3 Answers3

16

Just add space at the end of the format string:

"%[^=]=%[^;]; "

This will eat all whitespace characters, including new-lines.

Quotation from cplusplus.com:

Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).

Evgeny Kluev
  • 24,287
  • 7
  • 55
  • 98
8

An alternative is to use fgets() to read the entire line into a string, then use sscanf(). This has an advantage in debugging in that you can see exactly what data the function is working on.

Clifford
  • 88,407
  • 13
  • 85
  • 165
1

This will work:

fscanf(configuration,"%[^=]=%[^;];%[^\n]",name,option,dummy);

You will have to consume the new line character.Otherwise,the newline is left in the input stream.

askmish
  • 6,464
  • 23
  • 42
  • hmm...so how large should dummy be? Large enough to swallow all possible newline characters? – Yang Nov 04 '12 at 19:21
  • Since you said you have strict pre-defined format of input data, you could calculate the no. of characters exactly needed and create the dummy variable. This will help you find out any possible deviations from the input format, rather skipping them.(Which will happen if you use a space, before or after in fscanf or fgets). – askmish Nov 04 '12 at 19:46
  • 1
    There's a `%` missing near the end, anyway why not use `%[^=]=%[^;];%*[^\n]` and forget about those newlines and the buffer to contain them? – effeffe Nov 04 '12 at 19:56
  • @effeffe: Good idea that one, too. The OP's question stated that the input string format will be fixed, hence I used this approach, thinking it might be useful to find out if any line in the file fails the fixed-format criteria. :) – askmish Nov 04 '12 at 20:16