Как открыть и прочитать содержимое файла с путем Unicode или именем файла с помощью стандартного API?

0

Как открыть файл, путь или имя файла содержит символы Юникода и читать или записывать его без использования какого-либо специального API? Как это сделать, используя только библиотеки std, если это возможно или использует только API окон? Я попытался запустить std :: wifstream, чтобы открыть файл, как в примере кода ниже, но он не компилируется. Похоже, он не принимает аргумент "const wchar_t *", но "const char *". Я использую компилятор TDM-GCC 4.7.1, который включен в Dev-С++ IDE.

#ifndef UNICODE
#define UNICODE
#endif
...
#include <clocale>
#include <windows.h>
#include <fstream>
...
int main(int argc, char **argv)
{
    setlocale(LC_ALL, "Polish_Poland.852") ;
    ...
    fileCompare(first, second) ;
    ...
}
...
bool fileCompare(wstring first, wstring second)  // This function doesn't compile !
{
    using namespace std ;
    wifstream fin0(first.c_str(), ios::binary) ;
    wifstream fin1(second.c_str(), ios::binary) ;
    ...
}

Некоторый полный пример:

#ifndef UNICODE
#define UNICODE
#endif

#include <clocale>
#include <conio.h>
#include <windows.h>
#include <fstream>
#include <string>
#include <iostream>

using namespace std ;

bool fileCompare(wstring first, wstring second) ;

int main(int argc, char **argv)
{
    setlocale(LC_ALL, "Polish_Poland.852") ;

    wstring first, second ;
    first = L"C:\\A.dat" ;
    second = L"C:\\E.dat" ;

    fileCompare(first, second) ;

    getch() ;
    return 0 ;
}

bool fileCompare(wstring first, wstring second)  // This function doesn't compile !
{
    wifstream fin0(first.c_str(), ios::binary) ;
    wifstream fin1(second.c_str(), ios::binary) ;

}

Также, когда я заменяю L "C:\A.dat" и L "C:\E.dat" на строки, содержащие польские символы, он выдает ошибку о некорректной последовательности байтов.

  • 0
    Вы включили <string> ?
  • 1
    Было бы здорово, если бы вы действительно опубликовали полный пример, а не тот, который содержит ... магический код, который мы понятия не имеем, что это такое.
Показать ещё 6 комментариев
Теги:
unicode
filestream
gcc4.7

1 ответ

0

В wifstream не рассматривается проблема кодировки имени файла. Насколько мне известно, имена файлов wifstream и ifstream основаны не на wchar_t, а на основе char. Вы должны указать имя файла в кодировке символов, используемой вашей ОС, например, latin1, utf8 и т.д.

Однако wifstream позволяет вам читать поток wchar_t. Вы можете сообщить потоку, какой вклад вы ожидаете, создавая поток:

например

 // We expect the file to be UTF8 encoded
 std::locale locale("en_US.utf8");
 fin0.imbue(locale);

EDIT: если вам нужно преобразовать имена файлов (или любую строку) из wchar_t в соответствующую кодировку символов, вы можете глубже погрузиться в тему граничных разделов codecvt.

// Method translates wchar_t => pl_PL.iso88592" encoding
std::string to_string(const std::wstring & wstr)  
{ 

    typedef std::codecvt< wchar_t, char, std::mbstate_t > ccvt_t;  

    std::locale loc("pl_PL.iso88592");    

    const ccvt_t & facet = std::use_facet<ccvt_t>( loc );  

    std::string s;  
    {  
        std::mbstate_t st=mbstate_t();  

        const wchar_t *wac = wstr.c_str();  
        const wchar_t *wou = wac + wstr.length();  
        const wchar_t *wnx = wac;   

        ccvt_t::result r = ccvt_t::ok;  

        while(wou!=wnx && (r==ccvt_t::ok || r==ccvt_t::partial))  
        {  
            static const int l = 100;  
            static char cou[l];  
            char *cnx=NULL;  
            r = facet.out(st,wac,wou,wnx,cou,cou+l,cnx);  
            s+=std::string(cou,cnx-cou);  
            wac=wnx;  
        }  
    }  

    return s;  
} 

Какой тип std :: locale поддерживается и как вы можете указать его может быть зависимым от ОС.

  • 0
    А как насчет Windows API?
  • 0
    @ user1978386 Попробуйте использовать std :: locale locale ("Polish_Poland.852");
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню