我正在编写 C++ 代码,我希望执行以下操作:
在代码中有一个新类型 T,在 T 上定义了一个方法,它将一些信息打印到类型 FILE* 变量中。
我想在程序内部对这个字符串做一些工作,所以我想要一个字符串类型的变量(甚至是 char*),它将包含打印到屏幕上的内容(如果我将打印函数 stdout 指定为文件*)。
我怎样才能做到这一点 ?也许我可以创建一些 FILE* 变量,然后(以某种方式)使用我们创建的 File* 变量中存储的信息创建一个字符串/char* 变量?
任何帮助表示赞赏!
POSIX 1.2008 fmemopen,open_memstream函数创建一个FILE*指针,该指针写入(和/或读取)内存。
如果它不适用于您的平台(并且没有其他方法可以连接FILE *),那么您就不走运了。
我要尝试的下一件事是创建一个匿名管道 (POSIX pipe, Windows CreatePipe),将其写入端包装到FILE *(POSIXfdopen和 Windows_open_osfhandle以从 HANDLE 获取 CRT fd)。在这里,您必须确保管道的缓冲区大小足够,或者生成一个线程来读取管道。fflush方法完成后不要忘记写入端(或用于setbuf禁用缓冲)。
有几种独立于平台的方法可以做到这一点。在 C++ 中,您可以使用stringstream(http://www.cplusplus.com/reference/sstream/stringstream/),它有许多<<运算符重载。因此,如果您将ostream&(not oFstream) 的引用传递给输出方法,您可以轻松地在文件、标准输出流和字符串输出之间切换,因为所有这些流都继承自 ostream。然后,如果需要,您可以从中获取std::string对象并从中获取 C 字符串。stringstream
代码示例:
输出函数(或方法,则不需要示例中的第二个参数):
void PrintMyObjectToSomeStream(std::ostream& stream, const MyClass& obj)
{
stream << obj.pubField1;
stream << obj.pubField2;
stream << obj.GetPrivField1();
stream << "string literal";
stream << obj.GetPrivField2();
}
用法:
MyClass obj1;
std::ofsstream ofs;
std::stringstream sstr;
//...open file for ofs, check if it is opened and so on...
//...use obj1, fill it's member fields with actual information...
PrintMyObjectToSomeStream(obj1,std::cout);//print to console
PrintMyObjectToSomeStream(obj1,sstr);//print to stringstream
PrintMyObjectToSomeStream(obj1,ofs);//print to file
std::string str1=sstr.str();//get std::string from stringstream
char* sptr1=sstr.str().c_str();//get pointer to C-string from stringstream
或者你可以重载operator<<:
std::ostream& operator<<(std::ostream& stream, const MyClass& obj)
{
stream << obj1.pubField;
//...and so on
return stream;
}
那么你可以这样使用它:
MyClass obj2;
int foo=100500;
std::stringstream sstr2;
std::ofstream ofs;//don't forget to open it
//print to stringstream
sstr2 << obj2 << foo << "string lineral followed by int\n";
//here you can get std::string or char* as like as in previous example
//print to file in the same way
ofs << obj2 << foo << "string lineral followed by int\n";
使用FILEC 比 C++ 更多,但您可以考虑如何在fpirntf和sprintf或使用 Anton 的答案之间切换。