Удивительные результаты с std :: fstream - PullRequest
0 голосов
/ 03 ноября 2018

Я написал короткую программу для генерации равномерно распределенных случайных цифр и сохранения их в общий текстовый файл. Если я прошу его сгенерировать ровно 786432 цифры (пробелы каждые шесть цифр), выходные данные отображаются в виде случайных китайских и японских символов. Зачем? Я использую классы стандартной библиотеки для файлового ввода-вывода и 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;
}

Вывод с 786431 цифрами: 786431 digits, six digits/space

Вывод с 786432 цифрами: 786432 digits, six digits/space

Вывод с 786433 цифрами: 786433 digits, six digits/space

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Вот исправление. Я не уверен, что вызывает исходную проблему, но как только выражение if изменяется на:

if (!(charCtr % wordLen) && charCtr != 1
{
    txt << ' ';
//  charCtr += 1;    // This makes each word after the first 1 digit shorter.
}

окончательный .txt файл теперь отображается правильно, что устраняет проблему просмотра блокнота и все ваши слова теперь имеют 6 цифр, а не только первую.

enter image description here

Изначально я воспроизвел ту же проблему, скомпилировав ваш код с MSVS17 на Win 10 64bit:

enter image description here

0 голосов
/ 03 ноября 2018

Ответ ниже полезен, но на самом деле не исправил сообщенную проблему. Проблема была замечена только с редактором Windows notepad.exe. Он неправильно отображал файл в очень конкретном экземпляре. В любом случае, я надеюсь, что кто-то найдет ответ ниже полезным.


Использование new для создания потока файлов выглядит необычно и не требуется в этом коде. Это также означает, что вам нужно будет использовать delete для правильной очистки, закрытия и уничтожения объекта потока.

Заменить это:

std::fstream* txt = new std::fstream("randTxt.txt", std::ios::out);

с:

std::fstream txt("randTxt.txt", std::ios::out);

и ваши записи будут выглядеть так:

txt << rnd;

Когда объект потока выходит из области видимости, он красиво закрывает файл и освобождает все имеющиеся у него ресурсы.

...