Estoy trabajando con una herramienta de código abierto de UNIX que se implementa en C++, y tengo que cambiar el código para que haga lo que yo querer. Me gustaría hacer el menor cambio posible con la esperanza de que mi parche sea aceptado en la fase inicial. Se prefieren las soluciones que son implementables en C++ estándar y no crean más dependencias externas.C++: cómo obtener los resultados de fprintf como un std :: string sin sprintf
Aquí está mi problema. Tengo una clase de C++, llamémosla "A", que actualmente usa fprintf() para imprimir sus estructuras de datos con gran formato a un puntero de archivo. En su función de impresión, también llama recursivamente a las funciones de impresión definidas de forma idéntica de varias clases miembro ("B" es un ejemplo). Hay otra clase C que tiene un miembro std :: string "foo" que debe establecerse en los resultados print() de una instancia de A. Piense en ello como una función de miembro to_str() para A.
en pseudocódigo:
class A {
public:
...
void print(FILE* f);
B b;
...
};
...
void A::print(FILE *f)
{
std::string s = "stuff";
fprintf(f, "some %s", s);
b.print(f);
}
class C {
...
std::string foo;
bool set_foo(std::str);
...
}
...
A a = new A();
C c = new C();
...
// wish i knew how to write A's to_str()
c.set_foo(a.to_str());
debo mencionar que C es bastante estable, pero a y B (y el resto de las personas dependientes de a) se encuentran en un estado de flujo, por lo que los cambios necesarios cuanto mejor sea la menos código. La interfaz de impresión actual (ARCHIVO * F) también debe conservarse. He considerado varios enfoques para implementar A :: to_str(), cada uno con sus ventajas y desventajas:
Cambiar las llamadas a fprintf() para sprintf()
- yo no tendría que reescriba cualquier cadena de formato
- print() podría volver a implementarse como: fprint (f, this.to_str());
- Pero yo tendría que asignar manualmente char [] s, combinar una gran cantidad de cadenas de C, y finalmente convertir la matriz de caracteres a un std :: string
tratar de atrapar los resultados de A.Print() en una corriente de cadena
- tendría que convertir todas las cadenas de formato a formato < < salida. Hay cientos de fprintf() s para convertir: - {
- print() debería volverse a escribir porque no hay una forma estándar que sepa de crear una secuencia de salida desde un manejador de archivo UNIX (aunque this guy says it may be possible).
Usar cadena de Boost format library
- Más dependencias externas. Yuck. sintaxis
- de formato es lo suficientemente diferente de printf() para ser molesto:
printf (format_str, args) -> cout < < impulso :: formato (format_str)% arg1% arg2% etc
- QString::asprintf()
- Una dependencia externa diferente de
uso de Qt.
- Una dependencia externa diferente de
Por lo tanto, tienen que agotado todas las posibilidades? Si es así, ¿cuál crees que es mi mejor apuesta? Si no, ¿qué he pasado por alto?
Gracias.
Aunque ya respondí esta pregunta, también me gustaría señalar este proyecto: https://github.com/c42f/tinyformat, que resuelve el problema muy bien, y realmente hace un gran trabajo al reproducir la notación de formato de impresión. En estos días, uso ese paquete directamente, en lugar del método vsprintf que detallé hace unos años en mi otra respuesta. –