这是我的代码:
#include <iostream>
#include <time.h>
#include <fstream>
using namespace std;
int main()
{
int ms;
fstream t;
t.open( "time.txt", std::ios::in | std::ios::out );
t << time(NULL);
t >> ms;
cout << endl << " from file: " << ms;
cout << endl << " from time: " << time(NULL) << endl;
return 0;
}
我认为&#34;来自文件&#34;,&#34;来自时间&#34;应该是相同的(编辑:相似,不一样)。为什么不是?
输出:
form file: 4273382
from time: 1401823106
答案 0 :(得分:2)
TL; DR:您的信息流已缓冲,因此数据未准备好阅读。所以你看到的输出是m
的垃圾值。此外,写作后,阅读的位置也发生了变化。写入后使用t << std::flush
刷新数据,然后在阅读前重置t.seekg(0, std::ios_base::beg)
以重置位置。
问题在于您输出到流并假设在不是这种情况下立即写入输入。默认情况下缓冲流并在某些条件下刷新缓冲区(其中一个是在显式调用flush()
时或缓冲区用尽时)。由于这是一个简单的例子,缓冲作为效率措施可以忽略不计。您可以使用pubsetbuf()
:
t.open( "time.txt", std::ios_base::in | std::ios_base::out );
t.rdbuf()->pubsetbuf(nullptr, 0);
这些是您可以调用pubsetbuf()
并具有明确定义的行为的唯一参数。这将禁用流的缓冲,以便后续输出操作将数据直接发送到文件。或者,您可以拨打t.flush()
或执行t << std::flush
,只需按需刷新流。
下一个问题是您在写入后直接从流读取,这是错误的。双向文件流共享一个联合缓冲区,并被定义为具有同步的位置指示符。当输出操作移动 put 指针时, get 指针也是如此。在将数据读回程序时,必须将指针重置为开头。您可以使用seekg()
或seekp()
执行此操作。任何一个都会这样做,因为指针是同步的:
t << std::time(nullptr);
t.seekg(0, std::ios_base::beg);
t >> ms;
另外,不要忘记检查输入是否成功。如果它没有成功,你可能会因使用未初始化的变量而受到未定义行为的影响。
程序:
#include <iostream>
#include <fstream>
#include <ctime>
int main()
{
std::time_t ms;
fstream t("time.txt", std::ios::in | std::ios::out);
t.rdbuf()->pubsetbuf(nullptr, 0);
t << std::time(nullptr);
t.seekg(0, std::ios_base::beg);
if (t >> ms)
{
std::cout << " from file: " << ms << std::endl;
std::cout << " from time: " << std::time(nullptr) << std::endl;
}
}