Clang ++ — Как записать неанглийскую строку в файл и прочитать из этого файла с C ++?

Я хочу написать std::wstring на файл и нужно прочитать этот контент как std:wstring, Это происходит, как ожидается, когда строка L"<Any English letter>", Но проблема возникает, когда у нас есть такие персонажи, как бенгальский, каннада, японский и т. Д., Любые неанглийские буквы. Пробовал различные варианты, такие как:

  1. Преобразование std::wstring в std::string и записать в файл и время чтения читать как std::string и преобразовать как std::wstring
    • Запись происходит (я мог видеть из edito), но время чтения становится неправильным
  2. Пишу std::wstring на wofstream, это также не помогает
    буквы на родном языке std::wstring data = L"হ্যালো ওয়ার্ল্ড";

Платформа Mac и Linux, язык C ++

Код:

bool
write_file(
const char*         path,
const std::wstring  data
) {
bool status = false;
try {
std::wofstream file(path, std::ios::out|std::ios::trunc|std::ios::binary);
if (file.is_open()) {
//std::string data_str = convert_wstring_to_string(data);
file.write(data.c_str(), (std::streamsize)data.size());
file.close();
status = true;
}
} catch (...) {
std::cout<<"exception !"<<std::endl;
}
return status;
}// Read Method

std::wstring
read_file(
const char*  filename
) {
std::wifstream fhandle(filename, std::ios::in | std::ios::binary);
if (fhandle) {
std::wstring contents;
fhandle.seekg(0, std::ios::end);
contents.resize((int)fhandle.tellg());
fhandle.seekg(0, std::ios::beg);
fhandle.read(&contents[0], contents.size());
fhandle.close();
return(contents);
}
else {
return L"";
}
}

// Main

int main()
{
const char* file_path_1 = "./file_content_1.txt";
const char* file_path_2 = "./file_content_2.txt";

//std::wstring data = L"Text message to write onto the file\n";  // This is happening as expected
std::wstring data = L"হ্যালো ওয়ার্ল্ড";
// Not happening as expected.

// Lets write some data
write_file(file_path_1, data);
// Lets read the file
std::wstring out = read_file(file_path_1);

std::wcout<<L"File Content: "<<out<<std::endl;
// Let write that same data onto the different file
write_file(file_path_2, out);
return 0;
}

7

Решение

Как wchar_t вывод зависит от локали. По умолчанию
локаль ("C") вообще ничего не принимает кроме ASCII
(Юникод кодовые точки 0x20 … 0x7E, плюс несколько элементов управления
персонажи.)

Каждый раз, когда программа обрабатывает текст, самое первое утверждение в
main должно быть:

std::locale::global( std::locale( "" ) );

Если программа использует какой-либо из стандартных объектов потока, код
следует также наполнить их глобальной локалью, до любой
вход или выход.

3

Другие решения

Для чтения и записи файлов Unicode (при условии, что вы хотите писать символы Unicode) вы можете попробовать fopen_s

FILE *file;

if((fopen_s(&file, file_path, "w,ccs=UNICODE" )) == NULL)
{
fputws(your_wstring().c_str(), file);
}
0

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

Если вы имеете дело с текстовыми файлами, почему бы просто не использовать обычные операторы вывода и ввода << а также >> или другие текстовые функции, такие как std::getline?

0

Позднее редактирование: это для Windows (поскольку на момент ответа не было тега)

Вам нужно установить поток в локаль, которая поддерживает эти символы. Попробуйте что-то вроде этого (для UTF8 / UTF16):

std::wofstream myFile("out.txt"); // writing to this file
myFile.imbue(std::locale(myFile.getloc(), new std::codecvt_utf8_utf16<wchar_t>));

И когда вы читаете из этого файла, вы должны сделать то же самое:

std::wifstream myFile2("out.txt"); // reading from this file
myFile2.imbue(std::locale(myFile2.getloc(), new std::codecvt_utf8_utf16<wchar_t>));
0

Не используйте wstring или wchar_t. На не-Windows платформах wchar_t практически ничего не стоит Эти дни.

Вместо этого вы должны использовать UTF-8.

bool
write_file(
const char*         path,
const std::string   data
) {
try {
std::ofstream file(path, std::ios::out | std::ios::trunc | std::ios::binary);
file.exceptions(true);
file << data;
return true;
} catch (...) {
std::cout << "exception!\n";
return false;
}
}// Read Method

std::string
read_file(
const char*  filename
) {
std::ifstream fhandle(filename, std::ios::in | std::ios::binary);

if (fhandle) {
std::string contents;
fhandle.seekg(0, std::ios::end);
contents.resize(fhandle.tellg());
fhandle.seekg(0, std::ios::beg);
fhandle.read(&contents[0], contents.size());
return contents;
} else {
return "";
}
}

int main()
{
const char* file_path_1 = "./file_content_1.txt";
const char* file_path_2 = "./file_content_2.txt";

std::string data = "হ্যালো ওয়ার্ল্ড"; // linux and os x compilers use UTF-8 as the default execution encoding.

write_file(file_path_1, data);
std::string out = read_file(file_path_1);

std::wcout << "File Content: " << out << '\n';
write_file(file_path_2, out);
}
0
По вопросам рекламы [email protected]