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.
Format specifier for printf() function
A standard format specifier string takes the following form when using with printf() family of functions:
%[flags][width][.precision][length]specifier
Where:
- % - 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:
Specifier
The possible values of %specifier are:
Specifier | Description | Example |
---|---|---|
%% | Returns a percent sign | % |
%c | Character | A |
%d | Signed decimal integer (negative, zero or positive) | 105 |
%i | Signed decimal integer (negative, zero or positive) | 150 |
%u | Unsigned decimal number (zero or positive) | 8734 |
%e | Scientific notation using a lowercase | 1.245e+3 |
%E | Scientific notation using a uppercase | 1.245E+3 |
%f | Decimal floating point, lowercase | 453.25 |
%F | Decimal floating point, uppercase | 453.25 |
%g | Shorter of %e and %f | 453.25 |
%G | Shorter of %E and %f | 453.25 |
%p | Pointer address | 0x7fff07a75f68 |
%o | Unsigned octal | 723 |
%s | String of characters | Hello |
%x | Unsigned hexadecimal integer (lowercase letters) | 1fa |
%X | Unsigned hexadecimal integer (uppercase letters) | 1FA |
%a | Hexadecimal floating point (lowercase letters) | 0x1.fp3 |
%A | Hexadecimal floating point (uppercase letters) | 0x1.FP3 |
%n | Nothing 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. |
Sub-specifiers
Additional format values can be placed between the % and the specifier (e.g. %.3f) also known as sub-specifier. These sub-specifier are:
Flags
Flags | Description |
---|---|
- | 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. |
0 | Only left-pads numbers with zeros instead of spaces when padding is specified. |
Width
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.)
Precision
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.
Length
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 for printf() family of functions
Specifiers | |||||||
---|---|---|---|---|---|---|---|
length | d i | u o x X | f F e E g G a A | c | s | p | n |
(none) | int | unsigned int | double | int | char* | void* | int* |
hh | signed char | unsigned char | signed char* | ||||
h | short int | unsigned short int | short int* | ||||
l | long int | unsigned long int | double | wint_t | wchar_t* | long int* | |
ll | long long int | unsigned long long int | long long int* | ||||
j | intmax_t | uintmax_t | intmax_t* | ||||
z | size_t | size_t | size_t* | ||||
t | ptrdiff_t | ptrdiff_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:
2015-05-01
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 ] [catfish ] [ many cat] [many cat ] [many cat ]
Format specifier for scanf() function
The format string contains a sequence of characters that control how characters extracted from the stream are treated:
- Whitespace characters: any single whitespace character in the format string consumes all available consecutive whitespace characters from the input (determined as if by calling isspace() in a loop). Note that there is no difference between "\n", " ", "\t\t", or other whitespace in the format string.
- Non-whitespace character, except format specifier (%): each such character in the format string consumes exactly one identical character from the input stream, or causes the function to fail if the next character on the stream does not compare equal.
- Format specifiers: A sub-sequence beginning with % is used to specify the type and format of the data to be retrieved from the stream and stored into the locations pointed by the additional arguments.
A format specifier for scanf() family of functions follows this prototype:
%[*][width][length]specifier
Where:
- % - starting character of any format specifier
- [*][width][length] - sub-specifiers. Additional format values which can be placed between the % and the specifier.
Lets learn about specifier and sub-specifiers in detail:
Specifier
The following format specifiers are available:
specifier | Description | Characters extracted |
---|---|---|
i | Integer | Any number of digits, optionally preceded by a sign (+ or -). Decimal digits assumed by default (0-9), but a 0 prefix introduces octal digits (0-7), and 0x hexadecimal digits (0-f). Signed argument. |
d or u | Decimal integer | Any number of decimal digits (0-9), optionally preceded by a sign (+ or -). d is for a signed argument, and u for an unsigned. |
o | Octal integer | Any number of octal digits (0-7), optionally preceded by a sign (+ or -). Unsigned argument. |
x, X | Hexadecimal integer | Any number of hexadecimal digits (0-9, a-f, A-F), optionally preceded by 0x or 0X, and all optionally preceded by a sign (+ or -). Unsigned argument. |
a, A f, F e, E g, G | Floating point number | A series of decimal digits, optionally containing a decimal point, optionally preceded by a sign (+ or -) and optionally followed by the e or E character and a decimal integer (or some of the other sequences supported by strtof()). Implementations complying with C99 also support hexadecimal floating-point format when preceded by 0x or 0X. |
c | Character | The next character. The function reads exactly width characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end. |
s | String of characters | Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence. |
p | Pointer address | A sequence of characters representing a pointer. The particular format used depends on the system and library implementation, but it is the same as the one used to format %p in fprintf(). |
[characters] | Scanset | Any number of the characters specified between the brackets. A dash (-) that is not the first character may produce non-portable behavior in some library implementations. |
[^characters] | Negated scanset | Any number of characters none of them specified as characters between the brackets. |
n | Count | No input is consumed. The number of characters read so far and stored in the pointed location. |
% | % | A % followed by another % matches a single %. |
Except for n, at least one character shall be consumed by any specifier. Otherwise the match fails, and the scan ends there.
Sub-specifiers
Additional format values can be placed between the % and the specifier (also known as sub-specifier), which are as follows:
subs‑specifier | Description |
---|---|
* | An optional starting asterisk indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument). |
width | Specifies the maximum number of characters to be read in the current reading operation (optional). |
length | 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 for scanf() family of functions
Specifiers | |||||||
---|---|---|---|---|---|---|---|
length | d i | u o x X | f F e E g G a A | c | s | p | n |
(none) | int | unsigned int | double | int | char* | void* | int* |
hh | signed char | unsigned char | signed char* | ||||
h | short int | unsigned short int | short int* | ||||
l | long int | unsigned long int | double | wint_t | wchar_t* | long int* | |
ll | long long int | unsigned long long int | long long int* | ||||
j | intmax_t | uintmax_t | intmax_t* | ||||
z | size_t | size_t | size_t* | ||||
t | ptrdiff_t | ptrdiff_t | ptrdiff_t* | ||||
L | long double |
See <inttypes.h> for the specifiers for extended types.
Example: scanf() example
The example below shows the usage of scanf() function.
#include <stdio.h> int main (){ char fname [31], lname [31]; int age; int i; printf("Enter first name: "); scanf("%30s", fname); printf("Enter last name: "); scanf("%30s", lname); printf("Enter age: "); scanf("%d", &age); printf("%s %s is %d years old.\n\n", fname, lname, age); printf("Enter a hexadecimal number: "); scanf("%x", &i); printf("Entered value: %#x (%d)\n", i, i); return 0; }
The output of the above code will be:
Enter first name: John Enter last name: Smith Enter age: 25 John Smith is 25 years old. Enter a hexadecimal number: ff Entered value: 0xff (255)
Example: sscanf() example
The example below shows the usage of sscanf() function.
#include <stdio.h> int main (){ char mystr [] = "John 25 3000"; char name [20]; int age, salary; sscanf(mystr, "%s %i %i", name, &age, &salary); printf("%s is %i years old and earns %i dollars.\n", name, age, salary); return 0; }
The output of the above code will be:
John is 25 years old and earns 3000 dollars.