我有一个函数,它是来自库的回调,如下所示:
void onCallBack(int date, const std::stringstream &data);
我想将从data
变量收到的数据写入物理文件,所以我这样做:
void onCallBack(int date, const std::stringstream &data)
{
ofstream filePtr;
filePtr.open("data.file", ios::app);
string dataToWrite = data.str();
filePtr << dataToWrite.c_str();
filePtr.close();
}
回调onCallBack
函数在数据发生更新时被调用,我想将此更新数据写入文件。
问题是数据是std::stringstream
类型,它的行为类似于文件/缓冲区,并且从这个缓冲区我只想读取更新数据部分,例如:
在第一次回拨data
中包含字符串
this is first line
并在第二次回拨时包含:
this is first line
this is second line
在回调函数的第一次调用中,我将this is first line
字符串写入文件,在第二次回调中,我只想将this is second line
写入文件而不是第一行。
如何仅提取std::stringstream
的更新部分。
const std::stringstream &data
变量是常量,无法修改,或者我们无法使用tellg
或sync
。
UPDATE /编辑:
1.抱歉c标签。
2.对于使用read
,我们需要提供块大小来读取,我不知道块大小
3.您能否提供使用ios_base :: xalloc,ios:base :: iword和ios_base :: pword执行此操作的示例。
4.读取不是常数,但是告诉是
5.是的,没有人调用data.str("")
,它是来自lib的纯虚函数,在我的代码中我没有这样做。
答案 0 :(得分:2)
解决方案是记住你之前读过多少,然后根据需要只取出部分字符串。你如何做到这一点取决于你。您可以修改您的回叫以通过某种状态:
void onCallBack(int date, const std::stringstream &data, std::string::size_type& state);
如果它是界面的一部分(不太可能给出你发布的内容,但这是一般做回调的好方法),你可以将该状态存储为私有成员变量。
如果您不关心可重入且流不会缩小,您可以使用此示例中的static
变量进行快速破解,这是最容易显示在这里工作,但要求麻烦:
// What happens if you change the stringstream?
// This is why you need to re-think the callback interface
static std::string::size_type state = 0;
string dataToWrite = data.str().substr(state);
state += dataToWrite.size();
答案 1 :(得分:0)
如果您确定,每次调用回调的stringstream
对象都相同,您可以这样做:
filePtr << data.rdbuf() << std::flush;
答案 2 :(得分:0)
您可以在写入之前清除文件内容,方法是将ios::app
替换为ios::trunc
。
显然每次写入整个流并不是最佳的,但是如果你不能更改原型或刷新流而你不知道新数据的大小,那么我这是我唯一的方法想到这样做..