C ++:如何获取fprintf结果作为std :: string w / o sprintf [英] C++: how to get fprintf results as a std::string w/o sprintf

查看:764
本文介绍了C ++:如何获取fprintf结果作为std :: string w / o sprintf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个在C ++中实现的开源UNIX工具,我需要更改一些代码来让它做我想要的。我想做最小的可能的变化,希望我的补丁接受上游。首选可在标准C ++中实现并且不创建更多外部依赖性的解决方案。



这是我的问题。我有一个C ++类 - 让我们称之为A - 目前使用fprintf()打印其格式严重的数据结构到文件指针。在它的打印函数中,它也递归地调用几个成员类的相同定义的打印函数(B是一个例子)。还有另一个类C,它有一个成员std :: stringfoo,需要设置为一个A的实例的print()结果。认为它是A的to_str()成员函数。



在伪代码中:

  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();

...

//希望我知道如何写A的to_str()
c.set_foo(a.to_str());



我应该提到C是相当稳定的,但A和B都处于通量状态,所以代码变化越少越好。当前打印(FILE * F)界面也需要保留。我已经考虑了几种方法来实现A :: to_str(),每个都有优点和缺点:


  1. 将调用更改为fprintf ()to sprintf()




    • 我不必重写任何格式字符串

    • print ()可以重新实现为:fprint(f,this.to_str());

    • 但我需要手动分配char [] s,合并很多c字符串,最后将字符数组转换为std :: string


  2. 尝试捕获字符串中a.print




    • 我必须将所有格式字符串转换为<输出格式。有数百个fprintf()要转换: - {

    • print()必须重写,因为没有标准的方式,我知道从UNIX创建输出流文件句柄(虽然这个人
    • 使用Boost的字符串格式库




      • 更多的外部依赖。 Yuck。

      • 格式的语法与printf()有很大不同:



      printf (format_str,args) - > cout<< boost :: format(format_str)%arg1%arg2%etc


    • 使用Qt的 QString :: asprintf()




      • 另一个外部依赖。


如果是这样,你认为是我最好的赌注?

解决方案

谢谢。

我使用#3:boost字符串格式库 - 但我必须承认,我从来没有在格式规格的差异有任何问题。



对于我的外部依赖可能更糟(一个非常稳定的库)



编辑:添加一个如何使用boost :: format而不是printf的示例:

  sprintf(缓冲区,这是一个带有%s和%d数字的字符串,strings,42); 

与boost :: format库类似:

  string = boost :: str(boost :: format(This is a string with some%s and%d numbers)%strings%42) ; 

希望这有助于澄清boost :: format的用法



我在4或5个应用程序(将格式化的字符串写入文件,或自定义输出到日志文件)中使用boost :: format作为sprintf / printf替换,从来没有格式差异的问题。可能有一些(或多或少晦涩的)格式说明符不同 - 但我从来没有遇到过问题。



相比之下,我有一些格式说明我不能真正做流(尽管我记得)


I am working with an open-source UNIX tool that is implemented in C++, and I need to change some code to get it to do what I want. I would like to make the smallest possible change in hopes of getting my patch accepted upstream. Solutions that are implementable in standard C++ and do not create more external dependencies are preferred.

Here is my problem. I have a C++ class -- let's call it "A" -- that currently uses fprintf() to print its heavily formatted data structures to a file pointer. In its print function, it also recursively calls the identically defined print functions of several member classes ("B" is an example). There is another class C that has a member std::string "foo" that needs to be set to the print() results of an instance of A. Think of it as a to_str() member function for A.

In pseudocode:

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());

I should mention that C is fairly stable, but A and B (and the rest of A's dependents) are in a state of flux, so the less code changes necessary the better. The current print(FILE* F) interface also needs to be preserved. I have considered several approaches to implementing A::to_str(), each with advantages and disadvantages:

  1. Change the calls to fprintf() to sprintf()

    • I wouldn't have to rewrite any format strings
    • print() could be reimplemented as: fprint(f, this.to_str());
    • But I would need to manually allocate char[]s, merge a lot of c strings , and finally convert the character array to a std::string
  2. Try to catch the results of a.print() in a string stream

    • I would have to convert all of the format strings to << output format. There are hundreds of fprintf()s to convert :-{
    • print() would have to be rewritten because there is no standard way that I know of to create an output stream from a UNIX file handle (though this guy says it may be possible).
  3. Use Boost's string format library

    • More external dependencies. Yuck.
    • Format's syntax is different enough from printf() to be annoying:

    printf(format_str, args) -> cout << boost::format(format_str) % arg1 % arg2 % etc

  4. Use Qt's QString::asprintf()

    • A different external dependency.

So, have I exhausted all possible options? If so, which do you think is my best bet? If not, what have I overlooked?

Thanks.

解决方案

I am using #3: the boost string format library - but I have to admit that I've never had any problem with the differences in format specifications.

Works like a charm for me - and the external dependencies could be worse (a very stable library)

Edited: adding an example how to use boost::format instead of printf:

sprintf(buffer, "This is a string with some %s and %d numbers", "strings", 42);

would be something like this with the boost::format library:

string = boost::str(boost::format("This is a string with some %s and %d numbers") %"strings" %42);

Hope this helps clarify the usage of boost::format

I've used boost::format as a sprintf / printf replacement in 4 or 5 applications (writing formatted strings to files, or custom output to logfiles) and never had problems with format differences. There may be some (more or less obscure) format specifiers which are differently - but I never had a problem.

In contrast I had some format specifications I couldn't really do with streams (as much as I remember)

这篇关于C ++:如何获取fprintf结果作为std :: string w / o sprintf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆