Один текстовый файл сам меняет свою кодировку
Написал программу, которая записывает в разные файлы жанр, статус просмотра и названия, с последними двумя всё хорошо, но почему-то именно жанр никак не хочет сохраняться в кодировке 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 шт):
Команда sizeof p_name это константное значение, возвращающая размер типа переменной. В вашем случае размер указателя char *.
Писать в файл данные надо по размеру строки. То-есть используя strlen.
outside_name.write( p_name, strlen ( p_name ) );
При записи жанра вы передайте указатель на указатель, а потом грубо меняете тип на указатель на строку. Меняйте жёстко тип, только хорошо подумав.
outside_ganre.write( p_ganre, strlen ( p_ganre ));
Команда записи в файл передаёт только байты. Ей всё равно в какой они кодировке.
В функцию 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().