А именно использую ofstream и в самом файле записывается русскими буками хорошо, а вот с названием документа проблемы. Что только не пробовал, название файла получается что-то вроде такого �.txt (неверная кодировка)
Может я не совсем правильно задал вопрос, мне нужно чтобы программа сохраняла txt файл с названиями аа.txt аб.txt ав.txt - ... - яя.txt
Кратко расскажу суть программы: Есть словарь слов, расположенный в алфавитном порядке, программа должна разбить этот словарь по 33*33 документам (Минус 3*32, нет слов начинающихся с ь,ы,ъ). Документ аб.txt будет иметь все слова начинающиеся с аб...
Запись в файлы корректная, единственное, что названия файлов неправильные
Вот моя функция main()
int main() {
if (rfile.is_open()) {
while (getline(rfile, line)) {
string first, second;
try {
first = line[0];
second = line[1];
}catch (...) {
continue;
}
if (first == " " || first == "." || first == "-" || first == "|" || first == "," ||
second == " " || second == "|" || second == "-" || second == "." || second == ",")
continue;
string wfilename = first + second + ".txt";
ofstream wfile;
wfile.open(wdirectory + wfilename, ios_base::app);
if (wfile.is_open())
wfile << line;
wfile.close();
}
rfile.close();
}
else cout << "Unable to open file" << endl;
return 0;
}
Система Linux mint x64
Решение найдено! Я брал первые две буквы строки и использовал их для составления названия. Чтобы все корректно работало, нужно было конвертировать исходный файл в utf-8.
На linux эта команда выглядит как iconv -f windows-1251 < /home/user/filename.txt > /home/user/newEncodedFilename.txt
Знаки < и > обязательны. Далее уже использовать новый файл. Спасибо sercxjo
Ответ
Русские буквы в utf-8 обычно занимают 2 байта. Выбирая первые два байта из строки вы скорее всего получите только одну русскую букву, но возможно если первый из них другой символ или длина utf-8-представления символа более 2 байт, некорректно прерывается последовательность utf-8 кодировки. Для первого байта последовательности (x&192)==192, для остальных (x&192)==128. По этим признакам можно вырезать первую и вторую буквы (точнее в первом байте указывается длина последовательности в единичной системе исчисления, но будем надеяться на правильность исходных данных).
Таким образом, найти длину символа поможет функция:
int wlen(const string &x, int start)
{
if(x[start]==0) return 0;
if((x[start]&192)!=192) return 1;
int i=1;
while((x[start+i]&192)==128) i++;
return i;
}
Теперь остаётся заменить получение первого и второго символов строки:
first = line.substr(0, wlen(line, 0));
second = line.substr(first.size(), wlen(line, first.size()));
Ну и далее можно добавить анализ, что first.size()==0 || second.size()==0
Из беседы в чате выяснилось, что исходный файл в кодировке windows-1251.
Чтобы привести его в кодировку принятую в Linux Mint можно использовать команду iconv
iconv -f windows-1251 < исходный_файл > новый_файл
Если требуется включить перекодировку в саму программу, можно использовать libiconv пример
Комментариев нет:
Отправить комментарий