Format Strings

Introduction

Formatting data correctly during input/output (I/O) operations is essential for clear communication between computers. In C, format strings offer a powerful yet compact way to control this formatting. Many new C developers initially find format specifiers perplexing. For example:

printf("%02X", 15);

What exactly does %02X mean? This article clarifies such specifiers and demonstrates their usage through practical examples.

Numeric Representations: Decimal, Octal, Hexadecimal

We can represent numbers in different numeric systems easily:

#include <stdio.h>

int main() {
  int number = 255;
  /* We can write 255 as hex or octal. */
  if (number != 0xff || number != 0377) {
    return 1;
  }

  printf("Decimal: %d\n", number);
  printf("Octal: %o\n", number);
  printf("Hex: %x\n", number);
  printf("Capital hex: %X\n", number);

  return 0;
}

output:

❯ gcc file.c && ./a.out
Decimal: 255
Octal: 377
Hex: ff
Capital hex: FF

Floating-Point Precision

Control floating-point precision easily:

#include <stdio.h>

int main() {
  float number = 3.141592;

  printf("Float: %0.0f\n", number);
  printf("Float: %0.1f\n", number);
  printf("Float: %0.2f\n", number);

  return 0;
}

output:

❯ gcc file.c && ./a.out
Float: 3
Float: 3.1
Float: 3.14

Syntax: %.[precision]f

Padding with Zeroes

Use zero-padding to maintain numeric alignment:

#include <stdio.h>

int main() {
    float number = 3.141592;

    printf("%03.0f\n", number); // 003
    printf("%05.1f\n", number); // 003.1
    printf("%06.2f\n", number); // 003.14

    return 0;
}

output:

❯ gcc file.c && ./a.out
003
003.1
003.14

Syntax: %0[width].[precision]f

If zero-padding is not specified, spaces are used instead:

printf("%3.0f\n", 3.14); // '  3'

Character as Numeric

View numeric ASCII values:

#include <stdio.h>

int main() {
  printf("%c: %d\n", 'G', 'G');

  return 0;
}

output:

❯ gcc file.c && ./a.out
G: 71

String Alignment

Ensure neat alignment in output:

#include <stdio.h>

int main() {
  char *a = "some value";
  char *b = "some longer value";
  printf("%7s: %s\n", "Normal", a);
  printf("%7s: %s\n", "Long", b);

  return 0;
}

output:

❯ gcc file.c && ./a.out
 Normal: some value
   Long: some longer value

Use left-alignment with -:

#include <stdio.h>

int main() {
  char *str = "value";
  printf("%5s: %-10s\n", "Left", str);
  printf("%5s: %10s\n", "Rigth", str);

  return 0;
}

output:

❯ gcc file.c && ./a.out
 Left: value
Rigth:      value

Scientific Notation

Simplify representation of large/small numbers:

#include <stdio.h>

int main() {
  double number = 2E4;
  printf("Decimal: %.0f\n", number);
  printf("Scientific: %.0E\n", number);

  return 0;
}

output:

❯ gcc file.c && ./a.out
Decimal: 20000
Scientific: 2E+04

String Truncation

Limit string length neatly:

#include <stdio.h>

int main() {
  char *long_str = "very very very very long string";
  printf("%10s: %s\n", "Normal", long_str);
  printf("%10s: %.10s\n", "Truncated", long_str);

  return 0;
}

output:

❯ gcc file.c && ./a.out
    Normal: very very very very long string
 Truncated: very very

Using % Literal

To include a % character literally:

#include <stdio.h>

int main() {
  int number = 85;

  printf("%d%%\n", number);

  return 0;
}

output:

❯ gcc file.c && ./a.out
85%

Forcing Number Sign

Explicitly indicate positive numbers:

#include <stdio.h>

int main() {
  float negative = -1.5;
  float positive = 1.5; 
  printf("Negative: %+.2f\n", negative);
  printf("Positive: %+.2f\n", positive);

  return 0;
}

output:

❯ gcc file.c && ./a.out
Negative: -1.50
Positive: +1.50

Specifying padding dynamically

Specify padding as argument:

#include <stdio.h>

int main() {
    const char *s = "Hi";
    int w1 = 5, w2 = 10;

    printf("'%*s'\n",  w1, s);
    printf("'%*s'\n",  w2, s);

    return 0;
}

output:

❯ gcc file.c && ./a.out
'   Hi'
'        Hi'

Conclusion

C's format strings are an essential skill for effective debugging and displaying information. With practice, these specifiers quickly become second nature, greatly enhancing readability and correctness in your code.

Published:

Last updated:

Category: C

Comments

Leave a comment