Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

writing unicode characters/string to file

I'm trying to write unicode characters to file with std::wofstream but the put or write function doesn't write any characters.

Sample code:

#include <fstream>
#include <iostream>

int main()
{
    std::wofstream file;
    file.open("output.txt", std::ios::app);
    if (file.is_open())
    {
        wchar_t test = L'й';
        const wchar_t* str = L"фывдлао";
        file.put(test);
        file.write(str, sizeof(str));
        file.close();
    }
    else
    {
        std::wcerr << L"Failed to open file" << std::endl;
    }

    std::cin.get();
    return 0;
}

output.txt file is empty, no wchar/string is written after executing code, why? what am I doing wrong?

EDIT: Corected code:

#include <fstream>
#include <iostream>

int main()
{
    std::wofstream file;
    file.open("output.txt", std::ios::app);
    if (file.is_open())
    {
        wchar_t test = L'й';
        const wchar_t* str = L"фывдлао";
        file.put(test);
        if (!file.good())
        {
            std::wcerr << L"Failed to write" << std::endl;
        }
        file.write(str, 8);
        file.close();
    }
    else
    {
        std::wcerr << L"Failed to open file" << std::endl;
    }

    std::cin.get();
    return 0;
}

After applying code correction I'm presented with Failed to write but I still don't understand what do I need to do to write wide strings and chars?


2 Answers

I made it work this way, no need for external string libraries such as QString!

sole use of std libraries and c++11

#include <iostream>
#include <locale>
#include <codecvt>
#include <fstream>
#include <Windows.h>

int main()
{
    std::wofstream file;
    // locale object is responsible of deleting codecvt facet!
    std::locale loc(std::locale(), new std::codecvt_utf16<wchar_t> converter);

    file.imbue(loc);
    file.open("output.txt"); // open file as UTF16!

    if (file.is_open())
    {
        wchar_t BOM = static_cast<wchar_t>(0xFEFF);
        wchar_t test_char = L'й';
        const wchar_t* test_str = L"фывдлао";

        file.put(BOM);
        file.put(test_char);
        file.write(test_str, lstrlen(test_str));

        if (!file.good())
        {
            std::wcerr << TEXT("Failed to write") << std::endl;
        }

        file.close();
    }
    else
    {
        std::wcerr << TEXT("Failed to open file") << std::endl;
    }

    std::wcout << TEXT("Done!") << std::endl;

    std::cin.get();
    return 0;
}

File output:

йфывдлао

The first problem happens immediately: put is not capable of writing wide chars and stream will fail, however you never check whether first write succeeded:

file.put(test);
if(not file.good())
{
    std::wcerr << L"Failed to write" << std::endl;
}

Second problem is that sizeof(str) returns size of the pointer in bytes, not size of the string in bytes.

like image 30
user7860670 Avatar answered Sep 12 '25 03:09

user7860670



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!