Monday, 2 April 2012

The printf Function in C & C++

The printf Function.

The printf function in the C Standard I/O library <cstdio> is a useful and versatile way to send output to the stdout. Your output is a string that may include formatted variable values. The most basic form doesn't use any variables, such as:

printf("This output is a text string only. No variables.\n");

>This output is a text string only. No variable.

The next step is to include a variable as part of the output. For example,

char * Text = "A text string only from a variable.\n";
printf("%s", Text);

>A text string only from a variable.

The code %s is a format specifier for a character array or string. The %s is replaced by the value of Text. This principle applies to other data types. A decimal integer uses %d or %i.

int Salary = 375000;
printf("Salary is: %d.\n", Salary);
printf("Salary is: %i.\n", Salary);

>Salary is: 375000.
>Salary is: 375000.

The definition of the specifier is:


The square brackets means the parameter is optional. Hence, the most basic specifier is % followed by a letter of: c, d, i, e, E, f, g, G, o, s, u, x, X, p, or n.

This blog will go through examples of these specifiers and the various parameters. Once you understand the printf function, you can apply this knowledge in using the fprintf, fscanf, scanf, sprintf, sscanf functions.

Integer Data Types.

There are three specifiers for the integer data type in decimal format (Base 10). %d and %i apply to signed integers. %u applies to unsigned integers. If you use %u with a signed integer, the output will be garbage.

Salary = -35000;
printf("Using it with a negative value: %u doesn't work.\n\n", Salary);

>Using it with a negative value: 4294932296 doesn't work.

You can use an unsigned integer with %d or %i.

unsigned ActNum = 1234;
printf("Unsigned variable works with %%i or %%d. ActNum is %i.\n\n", ActNum);

>Unsigned variable works with %i or %d. ActNum is 1234.


You specify the width the value takes up by adding a number such as %8d or %8i. Setting a width allows you to align numbers.

int Salary = 12345678;
int Bonus = 52000;
printf("Salary is: %8d.\n", Salary);
printf("Bonus  is: %8d.\n", Bonus);

>Salary is: 12345678.
>Bonus  is:    52000.

If the number is larger than the width, the amount will be displayed, but the alignment will be askew.

int Salary = 1234567890;
int Bonus = 52000;
printf("Salary is: %8d.\n", Salary);
printf("Bonus  is: %8d.\n", Bonus);

>Salary is: 1234567890.
>Bonus  is:    52000.


The default is to align numbers to the right. You can add a minus sign such as %-8d to specify left alignment.

printf("Salary is: %-8d.\n", Salary);
printf("Bonus  is: %-8d.\n\n", Bonus);

>Salary is: 375000  .
>Bonus  is: 52000   .

Decimal. Hexadecimal. Octal.

To output a hexadecimal numbers use %x (lowercase) or %X (uppercase). An octal can be outputted with %o. It's the lowercase letter o for octal, not zero. See more examples here.

int num = 65535;
printf("Decimal: %d Hexadecimal: %X Octal: %o \n", num, num, num);
printf("Hexadecimal Uppercase: %X Lowercase: %x \n", num, num);

>Decimal: 65535 Hexadecimal: FFFF Octal: 177777
>Hexadecimal Uppercase: FFFF Lowercase: ffff

Use '#' to add a hex or octal notation prefix.

printf("Use # to create hexadecimal prefix '0X' or '0x'. Such as %#X, %#x.\n", num, num);

>Use # to create hexadecimal prefix '0X' or '0x'. Such as 0XFFFF, 0xffff.

printf("Use # to prefix octal with 0. Such as %#o.\n", num);
>Use # to prefix octal with 0. Such as 0177777.

int * pNum = &num;
printf("It works with pointers. Such as %#X, %#x.\n\n", pNum, pNum);

>It works with pointers. Such as 0X34EDD8, 0x34edd8.

Floating-point Numbers.

Floating point numbers use the f specifier such as %f.

float irrational = 123.456789;
double irrational2 = 123.456789;
printf("Default: %f \n", irrational);
printf("Default: %f \n", irrational2);

>Default: 123.456787
>Default: 123.456789

Set shorter decimal points.

printf("4 decimal points: %.4f \n", irrational);
printf("4 decimal points: %.4f \n", irrational2);

>4 decimal points: 123.4568
>4 decimal points: 123.4568

Set longer decimal points.

printf("14 decimal points: %.14f \n", irrational);
printf("14 decimal points: %.14f \n", irrational2);

>14 decimal points: 123.45678710937500
>14 decimal points: 123.45678900000000

Plus or Minus.

The flag + will show a plus sign or minus sign before a number.

Salary = 375000;
Bonus = -27500,
printf("Salary and bonus: %+d, %+d.\n", Salary, Bonus);

>Salary and bonus: +375000, -27500.

Padding With Zeroes.

The flag 0 (zero) places zeroes in front of a number. It only applies if a width has been specified.

Salary = 375000;
Bonus = 27500,
printf("Salary is: %08d.\n", Salary);
printf("Bonus  is: %08d.\n", Bonus);
printf("Salary is: %0d.\n", Salary);

>Salary is: 00375000.
>Bonus  is: 00027500.
>Salary is: 375000.

Scientific Notation.

Use %e or %E with a floating point number to display it in scientific notation. A number is formatted as: x.xxxxxxEnnn. The decimal equivalent is x.xxxxxx multiplied by 10 to the power of nnn.

double Notation = 100;
printf("100 is: %E.\n", Notation);

> 100 is: 1.000000E+002.

In base 10, a number greater than zero has 1s, 10s, 100s etc. So, 100 is 1 one-hundred. A common mistake happens when a number is less than zero. 0.001 is not 1/100 but 1/1000. So, 0.1 is tenths, 0.01 is hundreds, 0.001 thousands and so on.
Notation = 1.0/100.0;
printf("1/100 is: %f or %E.\n", Notation, Notation);

> 1/100 is: 0.010000 or 1.000000E-002.

double LargeNum = 123456789123;
printf("Number using E: %E.\n", LargeNum);
printf("Number using e: %e.\n", LargeNum);

>Number using E: 1.234568E+011.
>Number using e: 1.234568e+011.

printf("Specify width: %15E.\n", LargeNum);
printf("Specify decimals: %.2E.\n", LargeNum);

>Specify width:   1.234568E+011.
>Specify decimals: 1.23E+011.

double SmallNum = 0.123456789123;
printf("Number using E: %E.\n", SmallNum);

>Number using E: 1.234568E-001.

The scientific notation doesn't work with integer data types.

int Num = 100;
printf("Doesn't work with integers: %E.\n", Num);

>Doesn't work with integers: 5.820601E-308.

No comments:

Post a Comment