Lo que no entiendo para qué sirve es el 2 y el 1 que hay delante de la "d" y detrás del "%".
El valor entero inmediatamente después del carácter '%' indica la anchura del campo con una alineación (predeterminada) a la derecha con el propósito de permitir una impresión en columnas.
Por ejemplo con este programa:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main(void)
{
   char *test[] = {
      "a", 
      "bb",
      "ccc",
      "dddd"
   };
   size_t num_elem = sizeof test / sizeof test[0];
   size_t i;
 
   for (i = 0; i < num_elem; i++)
      printf("%5s %5d\n", test
[i
], (int) (i 
* pow(10, i
)));  
   return EXIT_SUCCESS;
}
Se genera la salida:
    a     0
   bb    10
  ccc   200
 dddd  3000
Puedes encontrar mas ejemplos mediante el motor de búsqueda de los foros.
----
El 2 se refiere a la cantidad de numeros a mostrar ej 8885 va mostrar 88 nada mas
No. Si los caracteres generados sobrepasan la anchura del campo se imprimen tal cual, como si la anchura nunca se hubiera indicado.
----
cual sería la diferencia entre mostrar string y mostrar caracteres?
"%c" imprime un carácter mientras que "%s" imprime una cadena (secuencia de caracteres terminada con el carácter '\0'). Por ejemplo:
char ch = 'X';
char str[] = "Hola";
 
printf("%s %c\n", str
, ch
); /* Imprime "Hola X" */ 
Yo algunas cosillas que he programado en c++ y lo que he aprendido en conclase, para las frases y demás utilizaba el tipo char, aunque más tarde me entere del tipo string en este foro, y me dijeron que era más correcto, por eso me gustaría saber la diferencia.
En el titulo del tema indicas que el lenguaje es C con "Duda básica sobre C:" pero ahora indicas que es C++, en el caso de este ultimo lo políticamente correcto es enfocarse en su biblioteca estándar: clase string, operadores ">>"/"<<" de las clases de entrada/salida, etc.
Un saludo