Todos sabemos que los especificadores de formato de C son enormemente potentes,
pudiendo formatear nuestra cadena resultante casi de cualquier forma que
queramos. ¿Casi? No. Faltan los separadores de miles. Podemos indicar el ancho,
el número de dígitos, la forma exponencial, cómo aparecerán los números
negativos, si se van a llenar de ceros por la derecha o no, e incluso la base,
pero los separadores de miles, no.
En detalle
Aunque voy a poner la forma para hacerlo en MFC, es muy fácil aplicar el método
a cualquier lenguaje/framework que trabaje con cadenas de forma similar y,
aunque el código parezca demasiado complejo, en realidad es muy sencillo de
entender.
Las cadenas MFC son objetos del tipo CString, que es un alias de CStringT y que
está relacionado con las cadenas ATL y en general es la forma que ha encontrado
Microsoft para uniformizar los varios tipos de cadenas que en su momento
polucionaron MFC y bibliotecas anexas.
Nosotros vamos a definir aquí una función que recibe un entero y devuelve una
cadena con el resultado formateado con separador de miles.
El código no es más que un ejemplo para que el lector se construya, en base a
éste, su propia función a su gusto.
El código
CString GetNumber2FormattedString(int number)
{
CString result;
result.Format(_T("%12d"),number);
int largo=result.GetLength();
for(int i=largo-3;i>0 && result[i]!=TCHAR(' ');i-=3)
result.Insert(i,TCHAR('.'));
return result;
}
Liosillo, ¿no? :-P
¿Cómo funciona?
Aunque en apariencia el código parece bastante abstruso, en realidad es muy
sencillo.
En primer lugar obtenemos una cadena formateada al modo clásico, que contendrá el
número convertido según el especificador de formato. Es aquí donde podemos
indicar cualquier otro formato.
Luego miramos cuántos caracteres ocupa y lo almacenamos en "largo". Y ahora sólo
tenemos que recorrer desde atrás hacia adelante la cadena e ir insertando el
punto del separador de miles, que podría ser cualquier otro valor.
El bucle se podría leer con palabras normales así: desde el largo menos tres (la
primera posición del primer separador a insertar), y mientras no hayamos llegado
al principio de la cadena (i>0) o esta tenga blancos (porque podríamos haber
ajustado una justificación. Aquí deberíamos comparar también con cualquier otro
caracter que nos indicara que nuestro número ha terminado pero la cadena sigue),
vamos descontando de tres en tres e insertando un punto en la citada posición.
Aquí hemos asumido algunas cosas: que se trata de un entero y que de ser negativo
no va a ir entre paréntesis ni corchetes, ni incorpora nigún otro prefijo (como
un signo menos), pero los cambios son fáciles de hacer.
Y eso es todo.