Я работаю с открытым исходным кодом UNIX, который реализован на C++, и мне нужно изменить код, чтобы заставить его делать то, что я хотеть. Я хотел бы внести минимальные изменения в надежде на то, что мой патч будет принят вверх по течению. Решения, которые реализуются в стандартном C++ и не создают больше внешних зависимостей, являются предпочтительными.C++: как получить результаты fprintf как std :: string w/o sprintf
Вот моя проблема. У меня есть класс C++ - назовем его «A» - в настоящее время используется fprintf() для печати его сильно форматированных структур данных в указатель файла. В своей функции печати он также рекурсивно называет идентично определенные функции печати нескольких классов-членов (пример «B»). Существует еще один класс C, в котором есть член std :: string «foo», который должен быть установлен для результатов print() экземпляра A. Подумайте об этом как функцию члена to_str() для A.
в псевдокоде:
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());
следует отметить, что C является достаточно стабильным, но а и в (и остальные иждивенцев страны а) находятся в состоянии потока, тем меньше изменений кода необходимо, тем лучше. Также необходимо сохранить текущий интерфейс печати (FILE * F). Я рассмотрел несколько подходов к реализации A :: to_str(), каждый из которых имеет свои преимущества и недостатки:
Изменить Призывы fprintf() в Sprintf()
- Я не должен был бы переписать любые строки формата
- print() может быть переопределен как: fprint (f, this.to_str());
- Но мне нужно будет вручную выделить полукокс [] S, объединить много строк гр, и, наконец, преобразовать массив символов в станде :: строку
попытаться поймать результаты a.print() в виде строки потока
- я бы преобразовать все строки формата в < < выходного формата. Есть сотни файлов fprintf() s для преобразования: - {
- print() пришлось бы переписать, потому что нет стандартного способа создания потока вывода из дескриптора файла UNIX (хотя this guy says it may be possible).
Использование строки Boost в format library
- Больше внешних зависимостей. Тьфу. Синтаксис
- Format является достаточно отличается от Е(), чтобы быть раздражающим:
Printf (format_str, арг) -> соиЬ < < подталкивание :: формат (format_str)% arg1% арг2% и т.д.
Использование Qt's QString::asprintf()
- Другая внешняя зависимость.
Итак, у меня исчерпаны все возможные варианты? Если да, то какой, по вашему мнению, мой лучший выбор? Если нет, что я забыл?
Спасибо.
Хотя я уже ответил на этот вопрос, я также хотел бы указать на этот проект: https://github.com/c42f/tinyformat, который прекрасно решает проблему и действительно отлично справляется с воспроизведением нотации форматирования printf. В наши дни я использую этот пакет напрямую, а не метод vsprintf, который я подробно описал несколько лет назад в своем другом ответе. – 2014-07-15 19:09:51