1
#ifndef UNICODE
#define UNICODE
#endif

#include <Windows.h>
#include <cstdio>
#include <fstream>

using namespace std;

int main()
{
    FILE* resFile;
    char multiByteStr[256];
    ifstream oFile;
    FILE* exampleFile;
    TCHAR buffer[256];      
    system("chcp 65001");

    resFile = _wfopen(L"foo",L"w, ccs=UTF-8");             
    fwprintf(resFile,L"%s",L"C:\\exsistingFolder\\zażółć gęśłą jaźń ☺☻♥♦• ć.txt");    
    fclose(resFile);   

    oFile.open(L"foo");    
    oFile.getline(multiByteStr,256,'\n');       
    oFile.close();    

    MultiByteToWideChar(CP_UTF8,0,multiByteStr,256,buffer,256);    
    wprintf(L"%s",buffer);

    exampleFile = _wfopen(buffer,L"w, ccs=UTF-16LE");       
    fwprintf(exampleFile,L"%s",buffer);     
    fclose(exampleFile);

    system("pause");
    return 0;
}

如您所见,程序应该创建文件“foo” resFile,其中包含要创建的文件的完整路径,并且这个新文件exampleFile应该包含自身的路径。尽管在 Visual Studio 2010 的调试过程中自动生成缓冲区具有正确的字符串,但不会创建 exampleFile。为什么?
还有一件事:为什么wprintf不输出扩展字符,虽然我已经将控制台的字体切换到了 Lucida Console - 可以处理未编码字符的那个。

附言。exampleFile 指向NULL,甚至在 之后_wfopen,并且 buffer 的最后一个字符是'/0'

4

3 回答 3

2

您没有进行任何错误处理。最重要的是,在调用 时MultiByteToWideChar(),您是在告诉它转换整个multiByteStr缓冲区,但大部分缓冲区都包含垃圾,因为您没有事先将其归零。您必须使用缓冲区中的实际字符数,而不是缓冲区的最大大小。MultiByteToWideChar()可能会返回您忽略的错误。代码中还有其他几个故障点。您需要始终检查错误,尤其是在与操作系统交互时。

试试这个:

#define UNICODE

#include <Windows.h>
#include <cstdio>
#include <fstream>

using namespace std;

void pause()
{
    wcin.ignore();
    wcin.get();
}

int main()
{
    FILE* resFile;
    char multiByteStr[256] = {0};
    ifstream oFile;
    FILE* exampleFile;
    WCHAR buffer[256] = {0};

    SetConsoleOutputCP(CP_UTF8);

    resFile = _wfopen(L"foo",L"w, ccs=UTF-8");
    if (!resFile) {
        wprintf(L"Unable to create foo");
        goto done;
    }

    fwprintf(resFile,L"%s",L"C:\\exsistingFolder\\zażółć gęśłą jaźń ☺☻♥♦• ć.txt");
    fclose(resFile);

    if (!oFile.open(L"foo")) {
        wprintf(L"Unable to open foo");
        goto done;
    }

    oFile.getline(multiByteStr,255,'\n');
    oFile.close();

    if (MultiByteToWideChar(CP_UTF8,0,multiByteStr,-1,buffer,256) == 0) {
        wprintf(L"Unable to convert UTF-8 to UTF-16. Error: %u", GetLastError());
        goto done;
    }

    exampleFile = _wfopen(buffer,L"w, ccs=UTF-16LE"); 
    if (!exampleFile) {
        wprintf(L"Unable to create file: %s", buffer);
        goto done;
    }

    fwprintf(exampleFile,L"%s",buffer); 
    fclose(exampleFile);

    wprintf(L"created file: %s", buffer);

done:
    pause();
    return 0;
}
于 2012-05-27T17:04:14.973 回答
1

为什么要混合搭配您的 I/O 库?这是一个纯(Windows)C 解决方案,减去错误检查:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE* pFile;
    wchar_t buffer[256];

    _wfopen_s(&pFile,L"foo",L"w, ccs=UTF-8");
    fputws(L"C:/existingFolder/zażółć gęśłą jaźń ☺☻♥♦• ć.txt",pFile);
    fclose(pFile);

    _wfopen_s(&pFile,L"foo",L"r, ccs=UTF-8");
    fgetws(buffer,_countof(buffer),pFile);
    fclose(pFile);

    _wfopen_s(&pFile,buffer,L"w, ccs=UTF-16LE");
    fputws(buffer,pFile);
    fclose(pFile);

    return 0;
}
于 2012-05-28T01:00:31.503 回答
1

解决方案非常简单—— _wfopen使用 BOM创建一个以 UTF-8 编码的文件,而 MultiByteToWideChar 函数不会删除 BOM,因此我们需要手动摆脱它。

于 2012-05-29T18:21:22.753 回答