Home/Blog/Programming/Format Specifiers in C
Home/Blog/Programming/Format Specifiers in C

Format Specifiers in C

izza ahmad
Dec 19, 2023
6 min read

Become a Software Engineer in Months, Not Years

From your first line of code, to your first day on the job — Educative has you covered. Join 2M+ developers learning in-demand programming skills.

Format specifiers are special operators that are responsible for indicating the data types used for both input and output. Simply put, a format specifier defines the data type involved when accepting an input or printing an output. While format specifiers can be found in numerous languages, in this blog, we'll focus solely  on format specifiers in C and learn how they work using various code snippets. And even if you’ve only had a basic introduction to C, you’ll be good to go for this lesson.

But before we get started, let’s understand how we usually deal with input and output in C.

Input and output in C#

Two major functions in C are the scanf() and printf() functions.

scanf()#

The function scanf() is common in C and is designed to receive user input from the standard input stream (e.g. keyboard in the user-specified format). Let’s learn how scan(f) works using the syntax below.

scanf() syntax#

scanf(format_specifier, &pointer_to_variable);

  • format_specifier refers to the second parameter’s data type. The user specifies the data type of the variable for which the user will provide a value to the program so that it can be interpreted accordingly.

  • &pointer_to_variable refers to the memory location where the variable is stored so that it can be updated once the user provides the input value.

printf()#

Another common C function, printf(), is responsible for outputting a string in the user-specified format to the standard output (e.g. screen). Let’s learn how this function works using the syntax below.

printf() syntax#

printf(const char * c_string, arguments ...)

  • const char * c_string refers to the C string that is to be outputted to the screen. Since it cannot be modified, it’s passed as const.

  • The count of arguments can be more than one if the string contains more than one variable to be outputted and each argument represents the data type of the corresponding variable in the string.

Note: We do not add the pointer (&) sign in the print function as the memory address for that value will not be updated with a new value. Learn more about pointers here.

Format specifiers and data types#

As discussed before, a particular format specifier is associated with a particular data type of the value that is to be printed or accepted. Depending on the particular use case, the variable could have any data type. The following table thoroughly explains what format specifier is to be used for what data type.

Format Specifier 

Syntax

Description

%d

int

Decimal integer or signed integer specifier

%c

char

Character specifier

%e

float

Scientific notation specifier

%f

float

Float specifier

%g

float

Fixed precision flat specifier

%u

unsigned int

Unsigned integer specifier

%x

int

Hexadecimal specifier

%ld

long

Long integer specifier

%lu

unsigned long

Unsigned long specifier

%lld

long long

Long long specifier

%llu

unsigned long long

Unsigned long long specifier

%lf

double

Double specifier

%Lf

long double

Long double specifier

%o

int

Octal specifier

%s

char array

String specifier

%n

int

Count specifier (prints nothing)

C code examples#

The use of a few format specifiers in C code is demonstrated through the short code snippets below. You can run them to see their output, and feel free to experiment with the code yourself — you’ll be a format-specifier expert in no time!

Decimal integer or signed integer specifier#

The following code demonstrates how to input and output decimal integers or signed integers. You can run the code below to see its output and experiment with it too.

#include <stdio.h>
int main(){
printf("Learning decimal integer specifiers today!\n\n");
int my_integer;
printf("Enter an integer value here = \n");
scanf("%d", &my_integer);
printf("The value obtained using the decimal integer specifier is = %d \n", my_integer);
return 0;
}

Enter the input below

Character specifier#

The following code demonstrates how to input and output characters. You can run the code below to see its output and experiment with it.

#include <stdio.h>
int main() {
printf("Learning character specifiers today!\n\n");
char my_character;
printf("Enter a character here = \n");
scanf(" %c", &my_character);
printf("The value obtained using the character specifier is = %c \n", my_character);
return 0;
}

Enter the input below

Scientific notation specifier#

The following code demonstrates how to input and output numbers in scientific notation.

#include <stdio.h>
int main() {
printf("Learning scientific notation specifiers today!\n\n");
float my_float_sci;
printf("Enter a float value here = \n");
scanf("%e", &my_float_sci);
printf("The value obtained using the scientific notation specifier is = %e \n", my_float_sci);
return 0;
}

Enter the input below

Float specifier#

The following code demonstrates how to input and output floating point numbers.

#include <stdio.h>
int main() {
printf("Learning float specifiers today!\n\n");
float my_float;
printf("Enter a float value here = \n");
scanf("%f", &my_float);
printf("The value obtained using the float specifier is = %f \n", my_float);
return 0;
}

Enter the input below

Note: Knowing the difference between float and double data types is important.

Fixed precision float specifier#

The following code demonstrates how to input and output floats with the same precision as initially given.

#include <stdio.h>
int main() {
printf("Learning float specifiers with fixed precision today!\n\n");
float my_float_prec;
printf("Enter a float value here = \n");
scanf("%g", &my_float_prec);
printf("The value obtained using the float specifier with fixed precision is = %g \n", my_float_prec);
return 0;
}

Enter the input below

Unsigned integer specifier#

The following code demonstrates how to input and output unsigned integers.

#include <stdio.h>
int main() {
printf("Learning unsigned integer specifiers today!\n\n");
unsigned int my_unsigned_integer;
printf("Enter an unsigned integer value here = \n");
scanf("%u", &my_unsigned_integer);
printf("The value obtained using the unsigned integer specifier is = %u \n", my_unsigned_integer);
return 0;
}

Enter the input below

Hexadecimal specifier#

The following code demonstrates how to input and output hexadecimal numbers.

#include <stdio.h>
int main() {
printf("Learning hexadecimal representation specifiers today!\n\n");
int my_hexadecimal;
printf("Enter a hexadecimal here = \n");
scanf("%x", &my_hexadecimal);
printf("The value obtained using the hexadecimal representation specifier is = %x \n", my_hexadecimal);
printf("The value in decimal format is = %d \n", my_hexadecimal);
return 0;
}

Enter the input below

Long integer specifier#

The following code demonstrates how to input and output long integers.

#include <stdio.h>
int main() {
printf("Learning long specifiers today!\n\n");
long my_long;
printf("Enter a long value here = \n");
scanf("%ld", &my_long);
printf("The value obtained using the long specifier is = %ld \n", my_long);
return 0;
}

Enter the input below

Unsigned long specifier#

The following code demonstrates how to input and output unsigned long integers.

#include <stdio.h>
int main() {
printf("Learning unsigned long specifiers today!\n\n");
unsigned long my_unsigned_long;
printf("Enter an unsigned long value here = \n");
scanf("%lu", &my_unsigned_long);
printf("The value obtained using the unsigned long specifier is = %lu \n", my_unsigned_long);
return 0;
}

Enter the input below

Long long specifier#

The following code demonstrates how to input and output long long integers.

#include <stdio.h>
int main() {
printf("Learning long long specifiers today!\n\n");
long long my_long_long;
printf("Enter a long long value here = \n");
scanf("%lld", &my_long_long);
printf("The value obtained using the long long specifier is = %lld \n", my_long_long);
return 0;
}

Enter the input below

Unsigned long long specifier#

The following code demonstrates how to input and output unsigned long long integers.

#include <stdio.h>
int main() {
printf("Learning unsigned long long specifiers today!\n\n");
unsigned long long my_unsigned_long_long;
printf("Enter an unsigned long long value here = \n");
scanf("%llu", &my_unsigned_long_long);
printf("The value obtained using the unsigned long long specifier is = %llu \n", my_unsigned_long_long);
return 0;
}

Enter the input below

Double specifier#

The following code demonstrates how to input and output double values.

#include <stdio.h>
int main() {
printf("Learning double specifiers today!\n\n");
double my_double;
printf("Enter a double value here = \n");
scanf("%lf", &my_double);
printf("The value obtained using the double specifier is = %lf \n", my_double);
return 0;
}

Enter the input below

Octal specifier#

The following code demonstrates how to input and output octal values.

#include <stdio.h>
int main() {
printf("Learning octal representation specifiers today!\n\n");
int my_octal;
printf("Enter an integer for octal representation here = \n");
scanf("%o", &my_octal);
printf("The value obtained using the octal representation specifier is = %o \n", my_octal);
return 0;
}

Enter the input below

String specifier#

The following code demonstrates how to input and output strings.

#include <stdio.h>
int main() {
printf("Learning string specifiers today!\n\n");
// add a string with a maximum length of 49
char my_string[50];
printf("Enter a string here = \n");
scanf("%s", my_string);
printf("The value obtained using the string specifier is = %s \n", my_string);
return 0;
}

Enter the input below

Note: Feel free to delve deeper into the use of n in printf as well.

Percentage printing specifier#

The following code demonstrates how to output the percentage sign.

#include <stdio.h>
int main() {
printf("Printing literal %% character today!\n");
return 0;
}

Why are format specifiers important?#

Format specifiers play a crucial role when it comes to interpreting and displaying data correctly. They have three main functions in programming: data representation, proper memory allocation, and input and output control.

Data representation: Format specifiers describe how variables with different data types should be parsed or formatted.

Proper memory allocation: Format specifiers help the compiler determine how much memory space to take for a particular variable depending on its type.

Input and output control: Format specifiers provide a standardized technique for incorporating variables within inputs or outputs and adding consistency in operations.

Rules for format specifiers#

Let’s review a key few rules to keep in mind when dealing with format specifiers.

1. Format specifiers always start with the percentage sign (%) followed by the data type symbol mentioned in the table above.

2. When there is more than one variable involved, it is necessary to maintain the correct order of arguments when compared to the order of format specifiers.

3. Ensure the printf() or scanf() statement matches the data type of the corresponding variable.

4. Buffer overflows can occur while using the string format specifier if the amount of memory needed for the string is insufficient. Extra precautions should be taken to avoid storage concerns.

5. Some format specifiers support changes in the precision and width of the involved variable. The next section explores such modifiers in detail.

Formatting the input or output#

The C language allows its users to correctly format an input or output by pairing some additional information with the format specifier.

Right justification: Adding a number between the % and the format specifier symbol results in the same amount of spaces before the involved variable.

Left justification: Adding a negative number between the % and the format specifier symbol results in the same amount of spaces after the involved variable.

Precision modifiers: For floating point integers (i.e. values with a decimal part), the precision for the decimal value can also be specified. Adding a .digit between the % and the f symbol represents the required number of acceptable places after the decimal point.

Note: For a shorter or completely unspecified field width, only the minimum number of characters in the original variable are printed.

Let’s see how to perform these formatting techniques in our code as well.

#include <stdio.h>
int main() {
int my_int = 42;
float my_float = 3.14159;
printf("Right Justification: %8d\n", my_int);
printf("Left Justification: %-8d\n", my_int);
printf("Shorter Field Width: %d\n", my_int);
printf("Precision Modifier: %.2f\n", my_float);
return 0;
}

And that marks the end of our discussion on format specifiers. From understanding how to handle input and output using formatted strings to learning more about coding specifiers for different data types, we’ve covered everything you need to know to work with format specifiers in C, even if you're learning C from scratch. You can now incorporate the correct specifiers and deal with your data types correctly.

Happy learning!


  

Free Resources