8

I'm using scanf to extract very regular tabular data. I need to go over it in two passes and can safely ignore some of the arguments some of the time. I want to allocate space for only the strings I care about and a single "discard" string for the others. If I pass this argument multiple times as output, is the behavior defined?

A silly minimal example:

char label[MAX_SIZE], discard[MAX_SIZE];
sscanf(input, "%s %s %s %s", discard, label, discard, discard);
porglezomp
  • 1,333
  • 12
  • 24
  • 1
    The assignments within `scanf()` are done sequentially so there should be no problem. – Jonathan Leffler Jan 06 '17 at 03:50
  • 5
    Why are you not doing `sscanf(input, "%*s %s %*s %*s", label);` using the ***assignment suppression operator***? – David C. Rankin Jan 06 '17 at 03:54
  • Because I'm actually passing the arguments to a function that extracts the fields after doing some other work, I just want to ignore those fields sometimes. – porglezomp Jan 06 '17 at 04:14
  • 2
    @DavidC.Rankin A reason to _not_ use `*` is to process the return value of `sscanf()` to note which part of `input` was assigned to `discard` in the case of an incomplete scan. IOWs, how much of the scan succeeded. – chux - Reinstate Monica Jan 06 '17 at 04:16
  • @DavidC.Rankin I vote this as a dupe, but did not want the dupe hammer as I hoped for additional votes to agree or disagree would be needed. Vote to re-open should you see fit. It appears to be a dupe of the title question, but not a dupe of the post's body. – chux - Reinstate Monica Jan 06 '17 at 04:20

2 Answers2

8

I cannot find any language in the C11 standard that makes your intended usage invalid.

There seems to be a better solution, though. If you place a * (“assignment suppression character”) after the % in the format string, then the scanf function will parse but not store the input item. Hence, you don't have to (must not, actually) provide a destination argument for it. Seems to be exactly what you need here.

5gon12eder
  • 24,280
  • 5
  • 45
  • 92
  • 1
    it is funny that something as simple as C can still have stuff hidden from me. – Grady Player Jan 06 '17 at 03:54
  • 1
    @GradyPlayer While I find the C programming language simple and elegant, the `scanf` function is a complex beast. So much that I avoid it if possible. – 5gon12eder Jan 06 '17 at 03:56
  • In this case I have a function that extracts it, and I want the fields some of the time. I'll probably end up doing something like you suggest and special casing it later. This one was more of a curiosity. – porglezomp Jan 06 '17 at 04:11
  • @5gon12eder, yeah I probably haven't ever actually used the scanf function outside of trying to repro problems people have on SO, etc... and if I am reading structured data from a file, I certainly am not using fscanf... I can plead scanf ignorance... – Grady Player Jan 06 '17 at 17:04
6

If I pass this argument multiple times as output, is the behaviour defined?

Citing C11:

7.21.6.2 The fscanf function

     int fscanf(FILE * restrict stream,
          const char * restrict format, ...);
  1. The fscanf function executes each directive of the format in turn. When all directives have been executed, or if a directive fails (as detailed below), the function returns.

The fscanf function (and therefore sscanf) executes each directive of the format in turn, therefore there should be no problems assigning to discard parameters multiple times, as the final assignment would have the final effect (overwriting the previous assignments).

artm
  • 17,291
  • 6
  • 38
  • 54