Search code examples
c++visual-c++textiofstream

Surprising results with std::fstream


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;
}

Output with 786431 digits: 786431 digits, six digits/space

Output with 786432 digits: 786432 digits, six digits/space

Output with 786433 digits: 786433 digits, six digits/space


Solution

  • 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.

    enter image description here

    Originally, I reproduced the same problem by compiling your code with MSVS17 on Win 10 64bit:

    enter image description here