【发布时间】:2018-11-03 04:41:02
【问题描述】:
我编写了一个简短的程序来生成均匀间隔的随机数字并将它们保存到通用文本文件中。如果我要求它准确生成 786432 位(每六位空格),输出将显示为随机的中文和日文字符。为什么? 我将标准库类用于文件 I/O 和 64 位 Xorshift 作为我的 PRNG。
程序(MSVC下编译):
#include <iostream>
#include <fstream>
#include <algorithm>
// From https://en.wikipedia.org/wiki/Xorshift
uint64_t xorsh64star(uint64_t* state)
{
uint64_t x = *state;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
state[0] = x;
return x * 0x2545F4914F6CDD1D;
}
int main()
{
uint64_t nDigits = 0;
uint64_t wordLen = 1;
std::cout << "How many digits?\n";
std::cin >> nDigits;
std::cout << "How many digits/word?\n";
std::cin >> wordLen;
std::fstream* txt = new std::fstream("randTxt.txt", std::ios::out);
std::cout << "writing...";
uint64_t charCtr = 0;
uint64_t xorshState = 1103515245U; // GLIB C init constant, from https://www.shadertoy.com/view/XlXcW4
for (uint64_t i = 0; i < nDigits; i += 1)
{
uint64_t rnd = xorsh64star(&xorshState) % uint64_t(9);
*txt << rnd;
charCtr += 1;
if (!(charCtr % wordLen) && charCtr != 1)
{
*txt << ' ';
charCtr += 1;
}
}
std::cout << "finished! :D";
return 0;
}
【问题讨论】:
-
为什么要使用
new来创建fstream?这很不寻常。您也没有使用delete,因此文件流可能没有很好地刷新和关闭。 -
我运行了您的程序(感谢您提供完整的运行示例!)并尝试了 786431、786432 和 786433(每个单词 6 位数字......)我所以想重复你的输出!但是,唉,在我使用 C++ 14 和 Apple LLVM 版本 10.0.0 (clang-1000.11.45.5) 的 Mac 上,我在所有三个尝试中都得到了常规的十进制数字。
-
我在我的机器上重现了这个问题。该文件在 Windows notepad.exe 中看起来是乱码。当我在任何其他文本编辑器(Notepad++、wordpad.exe 或 Visual Studio 编辑器)中打开它时,它看起来还不错。
-
@Blastfurnace 不知道我是怎么错过的,谢谢!在我的学位中,我们被教导为所有重要的事情假设
new。我在这里这样做是因为我不知道字符会在哪里缓冲(因为有人可以轻松输出千兆字节的文本......)。虽然我可能很傻。 @RayToal 释放流为我修补它;它一定是剩余的数据弄乱了后续的输出,而 clang + mac c++ 运行时的架构可以阻止这种情况的发生。 -
是的!感谢您的修复:)
标签: c++ visual-c++ text io fstream