0

我正在编写 C++ 代码,我希望执行以下操作:

在代码中有一个新类型 T,在 T 上定义了一个方法,它将一些信息打印到类型 FILE* 变量中。

我想在程序内部对这个字符串做一些工作,所以我想要一个字符串类型的变量(甚至是 char*),它将包含打印到屏幕上的内容(如果我将打印函数 stdout 指定为文件*)。

我怎样才能做到这一点 ?也许我可以创建一些 FILE* 变量,然后(以某种方式)使用我们创建的 File* 变量中存储的信息创建一个字符串/char* 变量?

任何帮助表示赞赏!

4

2 回答 2

4

POSIX 1.2008 fmemopenopen_memstream函数创建一个FILE*指针,该指针写入(和/或读取)内存。

如果它不适用于您的平台(并且没有其他方法可以连接FILE *),那么您就不走运了。

我要尝试的下一件事是创建一个匿名管道 (POSIX pipe, Windows CreatePipe),将其写入端包装到FILE *(POSIXfdopen和 Windows_open_osfhandle以从 HANDLE 获取 CRT fd)。在这里,您必须确保管道的缓冲区大小足够,或者生成一个线程来读取管道。fflush方法完成后不要忘记写入端(或用于setbuf禁用缓冲)。

于 2013-01-16T13:17:15.890 回答
1

有几种独立于平台的方法可以做到这一点。在 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++ 更多,但您可以考虑如何在fpirntfsprintf或使用 Anton 的答案之间切换。

于 2013-01-16T13:20:17.917 回答