Reputation: 346
I wrote a short program to generate evenly-spaced random digits and save them to a generic text file. If I ask it to generate exactly 786432 digits (spaces every six digits) the output displays as random Chinese and Japanese characters. Why? I'm using standard-library classes for file I/O and 64-bit Xorshift as my PRNG.
The program (compiled under 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;
}
Upvotes: 0
Views: 70
Reputation: 636
Here is the fix. I'm not sure what causes the original problem, but once the if
statement is changed to:
if (!(charCtr % wordLen) && charCtr != 1
{
txt << ' ';
// charCtr += 1; // This makes each word after the first 1 digit shorter.
}
the final .txt file is now shown properly, which fixes your notepad viewing problem and all your words now have 6 digits, not just the first one.
Originally, I reproduced the same problem by compiling your code with MSVS17 on Win 10 64bit:
Upvotes: 1
Reputation: 18652
The answer below is helpful but didn't actually correct the reported issue. The problem was only seen with the Windows notepad.exe editor. It incorrectly displayed the file in a very specific instance. In any case I hope someone finds the answer below useful.
Using new
to create the file stream looks unusual and isn't necessary in this code. Doing that also means you would need to use delete
to properly flush, close, and destroy the stream object.
Replace this:
std::fstream* txt = new std::fstream("randTxt.txt", std::ios::out);
with:
std::fstream txt("randTxt.txt", std::ios::out);
and your writes will look like:
txt << rnd;
When the stream object goes out of scope it will nicely close the file and release any resources it held.
Upvotes: 1