Один текстовый файл сам меняет свою кодировку

Написал программу, которая записывает в разные файлы жанр, статус просмотра и названия, с последними двумя всё хорошо, но почему-то именно жанр никак не хочет сохраняться в кодировке UTF-8. Вручную могу поменять кодировку, но при следующей записи она смениться обратно на ANSI сама по себе и вместо желаемого текста получится билеберда. Пробовал создавать новый файл, но проблема почему-то повторилась.

Часть кода, отвечающая за запись.

void set_name(char *p_name) {
    ofstream outside_name("C:\\Users\\dimak\\Desktop\\C++\\Фильмы 2.0\\Name.txt", ios::out | ios::app | ios::binary);
    outside_name.write((char*) p_name, sizeof p_name);
    outside_name.write("\n", 1);
}

void set_ganre(char* p_ganre) {
    ofstream outside_ganre("C:\\Users\\dimak\\Desktop\\C++\\Фильмы 2.0\\Ganre.txt", ios::out | ios::app | ios::binary);
    outside_ganre.write((char*)&p_ganre, sizeof p_ganre);
    outside_ganre.write("\n", 1);
}

void set_w_unw(char p_w_unw) {
    ofstream outside_w_unw("C:\\Users\\dimak\\Desktop\\C++\\Фильмы 2.0\\W_Unw.txt", ios::out | ios::app | ios::binary);
    outside_w_unw.write((char*) &p_w_unw, sizeof p_w_unw);
    outside_w_unw.write("\n", 1);
}

Пробовал вписать

    setlocale(LC_ALL, "ru");
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

но ситуацию это не изменило.


Ответы (2 шт):

Автор решения: AlexGlebe

Команда sizeof p_name это константное значение, возвращающая размер типа переменной. В вашем случае размер указателя char *.

Писать в файл данные надо по размеру строки. То-есть используя strlen.

outside_name.write( p_name, strlen ( p_name ) );

При записи жанра вы передайте указатель на указатель, а потом грубо меняете тип на указатель на строку. Меняйте жёстко тип, только хорошо подумав.

outside_ganre.write( p_ganre, strlen ( p_ganre ));

Команда записи в файл передаёт только байты. Ей всё равно в какой они кодировке.

→ Ссылка
Автор решения: DmitryK

В функцию set_name() вы передаете указатель на строку, и потом его же в .write() - всё правильно. А в функцию set_ganre() вы передаете указатель на строку, а внутри в .write() передаете уже адрес этого указателя, а не адрес строки (char*)&p_ganre. Вот и записывается мусор, лежащий начиная с адреса указателя. В файл записывается мусор, а не данные не в той кодировке.

void set_name(char *p_name) {
    outside_name.write((char*) p_name, sizeof p_name); // вместо sizeof надо strlen()
}

void set_ganre(char* p_ganre) {
    outside_ganre.write((char*) &p_ganre, sizeof p_ganre); // неправильно
// должно быть
    outside_ganre.write( p_ganre, strlen(p_ganre) );

}

Ну и правильно написал @AlexGlebe - количество байт для записи надо получать через strlen().

→ Ссылка