C Tutorial C References

C - Format Specifiers

A format specifiers is a sub-sequences beginning with % in the format string. It helps the compiler to understand the data types and formats in the input or output stream. It is used with scanf() and printf() family of functions while taking input and printing the output.

A standard format specifier string takes the following form:



  • % - starting character of any format specifier
  • [flags][width][.precision][length] - sub-specifiers. Additional format values which can be placed between the % and the specifier.

Lets learn about specifier and sub-specifiers in detail:


The possible values of %specifier are:

%%Returns a percent sign%
%dSigned decimal integer (negative, zero or positive)105
%iSigned decimal integer (negative, zero or positive)150
%uUnsigned decimal number (zero or positive)8734
%eScientific notation using a lowercase1.245e+3
%EScientific notation using a uppercase1.245E+3
%fDecimal floating point, lowercase453.25
%FDecimal floating point, uppercase453.25
%gShorter of %e and %f453.25
%GShorter of %E and %f453.25
%pPointer address0x7fff07a75f68
%oUnsigned octal723
%sString of charactersHello
%xUnsigned hexadecimal integer (lowercase letters)1fa
%XUnsigned hexadecimal integer (uppercase letters)1FA
%aHexadecimal floating point (lowercase letters)0x1.fp3
%AHexadecimal floating point (uppercase letters)0x1.FP3
%nNothing is printed. Returns the number of characters written so far by this call to the function. The result is written to the value pointed to by the argument. The corresponding argument must be a pointer to a signed int. The specification may not contain any flag, width, or precision. See the example below.


Additional format values can be placed between the % and the specifier (e.g. %.3f) also known as sub-specifier. These sub-specifier are:


-Left-justify within the given field width. Right justify is the default.
+Prefix positive numbers with a plus sign +. By default only negative are prefixed with a negative sign.
(space)If no sign is going to be written, a blank space is inserted before the value.
#When used with o, x or X specifiers the value is preceded with 0, 0x or 0X respectively for values different than zero.
When used with a, A, e, E, f, F, g or G specifiers, it forces the written output to contain a decimal point even if no more digits follow. By default, no decimal point is written if no digits follow.
0Only left-pads numbers with zeros instead of spaces when padding is specified.


An integer or * that specifies minimum field width. In the case when * is used, the width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. If the value to be printed is shorter than the width, the result is padded with blank spaces. (Note: This is the minimum width: The value is never truncated.)


Period . followed by an integer or *. In the case when * is used, the precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be converted. If the value of this argument is negative, it is ignored. If neither a number nor * is used, the precision is taken as zero.

  • For d, i, o, u, x and X specifiers: It signifies the minimum number of digits.
  • For a, A, e, E, f and F specifiers: It signifies the number of decimal digits.
  • For g and G specifiers: It signifies the maximum number of significant digits.
  • For s specifier: It specifies a cutoff point, setting maximum number of characters.


Modifies the length of the data type. For example - %i is used for signed decimal integer, with ll length sub-specifier it becomes %lli which can be used for long long int data type. Here is the complete list of length sub-specifier.

Length sub-specifier

lengthd iu o x Xf F e E g G a Acspn
(none)intunsigned intdoubleintchar*void*int*
hhsigned charunsigned char signed char*
hshort intunsigned short int short int*
llong intunsigned long int wint_twchar_t* long int*
lllong long intunsigned long long int long long int*
jintmax_tuintmax_t intmax_t*
zsize_tsize_t size_t*
tptrdiff_tptrdiff_t ptrdiff_t*
L long double

See <inttypes.h> for the specifiers for extended types.

Note: If multiple sub-specifiers are provided, they must be in %[flags][width][.precision][length]specifier order.

Example: Different specifiers

In the example below, the printf() function is used to print formatted data.

#include <stdio.h>
int main (){
  int x = 10;
  int * ptr;
  ptr = &x;

  printf("Characters: %c %c \n", 'b', 66);
  printf("Decimals: %d %i \n", 200, 300);
  printf("More Decimals: %ld %li \n", 20000L, 30000L);
  printf("Octals: %o %#o \n", 100, 100);
  printf("Hexadecimals: %x %#x %X %#X \n", 100, 100, 100, 100);
  printf("Strings: %s \n", "Hello");
  printf("Scientific notation: %e %E \n", 123.45, 123.45);
  printf("Floats: %2.0f %2.2f %2.4f \n", 3.1416, 3.1416, 3.1416);
  printf("Positive signed number = %+.2f \n", 3.1416); 
  printf("Padded number = %05d \n", 89);
  printf("Number with Width = %*d \n", 5, 89);
  printf("Pointer address = %p \n\n", ptr);

  int y;
  printf("Number of character printed so far in this line: %n", &y);
  printf("%d", y);
  return 0;

The output of the above code will be:

Characters: b B 
Decimals: 200 300 
More Decimals: 20000 30000 
Octals: 144 0144 
Hexadecimals: 64 0x64 64 0X64 
Strings: Hello 
Scientific notation: 1.234500e+02 1.234500E+02 
Floats:  3 3.14 3.1416 
Positive signed number = +3.14 
Padded number = 00089 
Number with Width =    89 
Pointer address = 0x7fff07a75f68 

Number of character printed so far in this line: 49

Example: Format date string

In the example below, this function is used to print formatted date string .

#include <stdio.h>
int main (){
  int year =  2015;
  int month = 5;
  int day = 1;
  //each format specifier specifies padding 
  //with 0 and width of the field
  printf("%04d-%02d-%02d", year, month, day);
  return 0;

The output of the above code will be:


Example: String specifiers

Consider one more example to see how to use string specifiers with a given character string.

#include <stdio.h>
int main (){
  char x[] = "catfish";
  const char* y = "many catfishes";

  printf("[%s]\n", x);            //standard string
  printf("[%10s]\n", x);          //right-justified with spaces
  printf("[%*s]\n", 10, x);       //right-justified with spaces
  printf("[%-10s]\n", x);         //left-justified with spaces
  printf("[%-*s]\n", 10, x);      //left-justified with spaces
  printf("[%10.8s]\n",  y);       //right-justified (8 characters cutoff)
  printf("[%-10.8s]\n", y);       //left-justified (8 characters cutoff)
  printf("[%-*.*s]\n", 10, 8, y); //left-justified (8 characters cutoff)
  return 0;

The output of the above code will be:

[   catfish]
[   catfish]
[catfish   ]
[catfish   ]
[  many cat]
[many cat  ]
[many cat  ]