c++ - snprintf - ¿Las funciones de E/S con formato C(printf, sprintf, etc.) son más populares que IOStream y, de ser así, por qué?
scanf (6)
He estado revisando un montón de códigos hechos por otros últimamente y he notado que todos usan mucho las funciones C del estilo "printf", pero las funciones de C ++ aprendidas en la escuela (específicamente, en particular) no parecen ser tan populares.
¿Es esta una observación válida, y hay una razón para esto? ¿Convención?
Gracias,
R
Creo que el gusto es una posible razón. Personalmente encuentro esto:
printf("%8d: %s/n", customer->id, customer->name);
más legible que esto:
std::cout << customer->id << ": " << customer->name << std::endl;
También está el problema con la localización. printf
hace posible cambiar el formato para adaptarse a otros idiomas y culturas de IU, lo que se convierte en una tarea importante con iostreams
, a menos que use algo como la biblioteca de formatos de Boost .
Donde trabajo, utilizamos el formato de estilo printf
. Esto se debe a que solíamos hacer un uso intensivo de la clase CString
MFC y su método de Format
estilo de Format
. Hemos estado eliminando el MFC, pero no hemos cambiado nuestro enfoque de formato de cadena.
En cuanto a cuál está diseñado mejor, vea ¿Quién diseñó / diseñó las transmisiones IOS de C ++, y aún se consideraría bien diseñado según los estándares actuales?
Hay varias críticas al sistema de flujo estándar, sobre todo porque no suele ser tan eficaz como el sistema de C, y que no permiten el reordenamiento de los elementos a formatear, lo que puede dificultar la localización.
Personalmente, uso secuencias para la mayoría de todo, porque me permiten tener una función de escritura en una consola, un archivo o una cadena, sin tener que modificar la función.
Las funciones de la familia printf y scanf tienen dos problemas principales: seguridad de tipo y seguridad de memoria. Es bastante fácil hacer una discrepancia entre la cadena de especificación y la lista de argumentos de longitud variable que sigue. Además, los desbordamientos de búfer a través de scanf son una vulnerabilidad de seguridad clásica. En resumen, no los uses.
Los flujos de C ++ ofrecen seguridad de tipo y memoria, y también la capacidad de extensión de formato. Son mucho más potentes y generalmente más fáciles de usar que printf y scanf.
Además, como lo sugiere ShaderOp, la biblioteca de formatos de Boost ofrece la misma seguridad, pero hace que los programadores de C se sientan más cómodos.
Personalmente, uso printf
sobre las cosas de iostream
(como cout
) porque creo que es más claro.
Cuando realiza el formateo con iostream
, tiene que <<
todo tipo de rarezas como setiosflags
y setf
. Nunca puedo recordar en qué espacio de nombres vive todo esto, por no hablar de lo que hace todo. Incluso cuando lo hago, estoy decepcionado con el aspecto detallado e intuitivo del código.
Las opciones de formato con printf
pueden parecer ilegibles al principio, pero son concisas, están claramente documentadas en una sola página de manual y son comunes a una amplia gama de idiomas.
Otra ventaja es que printf
tiene estado: a diferencia de cout
, no necesito recordar qué funciones miembro se han llamado en printf
, o qué mezcla bizantina de banderas ha sido " <<
" en ella. Esta es una gran ventaja para la legibilidad.
Voy a adivinar que el printf es más usado porque
- estuvo en uso durante algunos años antes de que aparecieran los compiladores y flujos de C ++
- C se usa más que C ++
- se realizaron muchas operaciones de E / S para cosas como la API de Windows, para las cuales printf es un ajuste natural entre Abrir / Leer / Escribir / Cerrar / etc