我正在使用一个用C++实现的开源UNIX工具,我需要更改一些代码才能让它做我想做的事情.我想做出尽可能小的改变,希望上传接受我的补丁.可以在标准C++中实现并且不创建更多外部依赖性的解决方案是首选.
这是我的问题.我有一个C++类 - 我们称之为"A" - 目前使用fprintf()将其格式严格的数据结构打印到文件指针.在其print函数中,它还递归调用几个成员类的相同定义的打印函数("B"是一个例子).还有另一个C类,它有一个成员std :: string"foo",需要设置为A实例的print()结果.把它想象成A的to_str()成员函数.
在伪代码中:
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());
Run Code Online (Sandbox Code Playgroud)
我应该提到C是相当稳定的,但是A和B(以及A的其余部分)处于不稳定的状态,因此所需的代码变化越少越好.还需要保留当前的打印(FILE*F)界面.我已经考虑了几种实现A :: to_str()的方法,每种方法都有优点和缺点:
将对fprintf()的调用更改为sprintf()
尝试在字符串流中捕获a.print()的结果 …
我需要做两次(或更多次)传球va_list.我有一个大小的缓冲区,我想用sprintf写一个格式化的字符串.如果格式化的字符串不适合分配的空间,我想要将分配的空间加倍并重复直到它适合.
(作为旁注,我希望能够首先计算格式化字符串的长度并分配足够的空间,但我发现可以做到的唯一功能是_snprintf,并且在VS2005中不推荐使用...)
现在,到目前为止没有问题:我在每次调用之前使用vsnprintf和va_start调用.
但我还创建了一个函数,它将a va_list作为参数,而不是"......".然后我不能再使用va_start了!我已经读过了va_copy,但VS2005不支持它.
那么,你会怎么做?
我读了一点关于 C/C++ 中的可变参数函数,我发现一个线程提到在 GCC 中重用 va_list 你需要使用它的副本和 va_copy 并且在他们建议的同一个线程上定义它
#define va_copy(d,s) ((d) = (s))
这意味着它只是将 va_list s 的值分配给 va_list d。
改用它va_list ap1 = va_list ap不是更易读吗?创建另一个名为 va_copy 的函数有什么意义?