60

In some code that I have to maintain, I have seen a format specifier %*s . Can anybody tell me what this is and why it is used?

An example of its usage is like:

fprintf(outFile, "\n%*s", indent, "");
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Aamir
  • 14,882
  • 6
  • 45
  • 69

6 Answers6

65

It's used to specify, in a dynamic way, what the width of the field is:

  • The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

so "indent" specifies how much space to allocate for the string that follows it in the parameter list.

So,

printf("%*s", 5, "");

is the same as

printf("%5s", "");

It's a nice way to put some spaces in your file, avoiding a loop.

sth
  • 222,467
  • 53
  • 283
  • 367
akappa
  • 10,220
  • 3
  • 39
  • 56
  • 5
    @EthanHeilman, the * means something COMPLETELY different in the scanf family of functions. – John Hascall Sep 06 '14 at 20:56
  • Note that if you have a negative number, the field will be left justified. That is, `printf("[%*s]\n", -10, "hello")` will output "`[hello     ]`" rather than "`[     hello]`" which you would get if you use `+10` (or `10`). – Jonathan Leffler Sep 02 '17 at 23:45
11

Don't use "%*s" on a buffer which is not NULL terminated (packed) thinking that it will print only "length" field.

user2132064
  • 119
  • 1
  • 2
  • 34
    Use "%.*s" to achieve this! – Andy G Feb 19 '15 at 09:28
  • @AndyG I am having trouble understanding how '%.*s' helps with that. From the docs [here](https://en.cppreference.com/w/c/io/fprintf), it looks like the only difference between the 2 format specifiers is that '%.*s' ignores negative precision values. – powersource97 Sep 17 '21 at 03:06
  • 3
    @powersource97, `%.*s` means you are reading the `precision` value from an argument, and precision is the maximum number of characters to be printed, and `%*s` you are reading the `width` value from an argument, which is the minimum number os characters to be printed. – Vargas Sep 24 '21 at 20:50
4

The format specifier %4s outputs a String in a field width of 4—that is, printf displays the value with at least 4 character positions.

If the value to be output is less than 4 character positions wide, the value is right justified in the field by default.

If the value is greater than 4 character positions wide, the field width expands to accommodate the appropriate number of characters.

To left justify the value, use a negative integer to specify the field width.

References: Java™ How To Program (Early Objects), Tenth Edition

Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
2

When used in printf and fprintf:

printf("%*s", 4, myValue); is equivalent to printf("%4s", myValue);

It displays the variable with minimum width, rest right-justified spaces. To left-justify the value, use a negative integer.

When used in scanf and sscanf:

/* sscanf example */
#include <stdio.h>

int main ()
{
  char sentence []="Rudolph is 12 years old";
  char str [20];
  int i;

  sscanf (sentence,"%s %*s %d",str,&i);
  printf ("%s -> %d\n",str,i);
  
  return 0;
}

Output:

Rudolph -> 12

It is used to ignore a string.

Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
zeitgeist
  • 852
  • 12
  • 19
  • 1
    in `sscanf()`, `"%s"` is worse than [`gets()`](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) as it lacks a width limit. – chux - Reinstate Monica Nov 07 '21 at 03:31
1

* Causes fprintf to pad the output until it is n characters wide, where n is an integer value stored in the a function argument just preceding that represented by the modified type.

printf("%*d", 5, 10) //will result in "10" being printed with a width of 5.
jitter
  • 53,475
  • 11
  • 111
  • 124
1

http://www.cplusplus.com/reference/clibrary/cstdio/printf/

The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

e.g: printf("%*s", 4, myValue); is equivelant to printf("%4s", myValue);.

pauldoo
  • 18,087
  • 20
  • 94
  • 116