1

Is this ever acceptable?

fprintf(fp,"Just a string");

or

fprintf(fp,stringvariable);

versus

fprintf(fp,"%s","Just a string");

It seems confusing to me as the string variable (or constant) is used as the formatting versus the output itself. It the string variable had format-specific content ('%s', etc.) then the output would not be as intended.

For string-only output (no formatting) which is better?

fprintf(fp,"%s",stringvariable);

or

fputs(stringvariable,fp);
Jiminion
  • 5,080
  • 1
  • 31
  • 54
  • You can safely `printf()` a string-literal (you can't avoid it anyway). But if the string is mutable, especially by user-supplied data, you risk format-string vulnerabilities. – EOF Nov 12 '15 at 15:31

1 Answers1

2

It is acceptable if you "know" the string variable to be "clean", if you don't care about the warning most modern compilers generate for that construct. Because:

  1. If your string contains conversion specifiers "by accident", you are invoking undefined behaviour.

  2. If you read that string from somewhere, a malicious attacker could exploit point 1. above to his ends.

It's generally better to use puts() or fputs() as they avoid this problem, and consequently don't generate a warning. (puts() also tosses in an automatic '\n'.)

The *puts() functions also have (marginally) better performance. *printf(), even on nothing more than "%s" as format string, still has to parse that conversion specifier, and count the number of characters printed for its return value.

Thanks to users 'rici' and 'Grady Player' for pointing out the character counting and compiler warning. My C got a bit rusty it seems. ;-)

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 3
    fprintf returns the number of characters printed, so %n is irrelevant. I'd say that it is *always* better to use fputs (not puts, unless you want the extra newline) and that the fprintf idiom asked about is *not* acceptable (in a code review done by me, at least), but I suppose that's a matter of opinion. – rici Nov 12 '15 at 15:37
  • 2
    I upvoted because there is a lot of info, but modern compilers have a warning for using a variable as the format string... I think it is just a good habit not to do that – Grady Player Nov 12 '15 at 15:38
  • My issue is I have some strings with no formatting and some with formatted ints or floats or whatever. So, as they change, it is a pain to completely change the call and order of arguments. Which leads me toward fprintf(fp,"%s",var). – Jiminion Nov 12 '15 at 15:43
  • Thank you. This is sort of a style question, but the vulnerability concern is something I can hang my hat on. Not too concerned about the performance. – Jiminion Nov 12 '15 at 15:56