0

I'm trying to see if when I do

fscanf(inputSTREAM, "$%s$", out) 

I can also return the $ signs - is there a way?

Rio
  • 14,182
  • 21
  • 67
  • 107

3 Answers3

1

I don't think there's a way to retrieve the string with the dollar signs and the non-blank string between them using the scanf() family of functions. The closest approach would probably be using a scanset, but scansets are not the same as regular expressions, and you'd need a regular expression to specify the pattern you are looking for.


In practice, you could probably get the first dollar sign into the string using:

fscanf(inputSTREAM, " %1[$]%[^$]%*[$]", &out[0], &out[1]);

You can't pull the same stunt for the latter dollar sign, even if you know the exact length of the string. The trouble is that you'd need to overwrite the null at the end of the string with the second dollar sign, and you'd want a NUL '\0' after the string. Adding the final dollar is much easier than inserting the first at the beginning of the string. The third scanset contains an assignment-suppressing '*' and requires a dollar at the end. The leading space in the format skips spaces.

This isn't guaranteed behaviour; the first conversion would write a NUL over out[1], and the second conversion would then write the string over out[1], but the C standard does not guarantee that it will work.

#include <stdio.h>
int main(void)
{
    char out[20];

    scanf(" %1[$]%[^$]%*[$]", &out[0], &out[1]);
    printf("<<%s>>\n", out);
    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

Note that in "$%s$" the second dollar is useless, as %s means "sequence of non-white space characters". So, the terminating dollar is already scanned by the %s. All you need to do is scan the initial dollar with %c at the beginning, e.g. try this:

#include <stdio.h>

int main (void)
{
    char out[64];

    while (fscanf (stdin, " %c%62s", &out[0], &out[1]) == 2 && out[0] == '$') {
        printf (">>%s<<\n", out);
    }
    return 0;
}

$ ./a.out
$fooo$
>>$fooo$<<
$bar$
>>$bar$<<
   $baz   $
>>$baz<<
  $  boing   $
>>$$<<
$ ./a.out
  $zap$
>>$zap$<<
  $   oink$
>>$oink$<<
^D
$

Note that 62 in %62s is two less than the sizeof out to leave room for the initial dollar and terminating 0.

Jens
  • 69,818
  • 15
  • 125
  • 179
0

You could read the line as a string, then use sscanf to get the value you're using fscanf for. Then you'll have the original string and the value from sscanf.

tamarintech
  • 1,972
  • 12
  • 17