#include <iostream>
#include <Windows.h>
#include <locale>
#include <string>
#include <codecvt>
typedef wchar_t* LPWSTR, *PWSTR;
template <typename Facet>
struct deletable_facet : Facet
{
using Facet::Facet;
};
int main(int argc, char *argv[])
{
std::cout << argv[0] << std::endl;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
//std::wcout << converter.from_bytes(argv[0]) << std::endl; // range error
std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>> conv;
std::wstring ns = conv.from_bytes(argv[0]);
std::wcout << ns << std::endl;
wchar_t filename[MAX_PATH];
//GetModuleFileName(NULL,filename,MAX_PATH); // cant convert wstring_t* to char*
GetModuleFileNameW(NULL,filename,MAX_PATH);
std::wcout << filename << std::endl;
getchar();
return 0;
}
输出:
C:\Users\luka\Desktop\ⁿ?icΣ\unicode.exe
C:\Users\luka\Desktop\ⁿ?icΣ\unicode.exe
C:\Users\luka\Desktop\ⁿ
该文件夹的实际名称为üлicä
大约2个小时以来,我一直在尝试许多不同的方法,据我所见,人们建议使用GetModuleFileName,但是您可以看到返回转换错误(typedef wchar_t * LPWSTR,* PWSTR;尚未修复)。
那么有什么方法可以获取unicode中的当前文件夹路径,并将其余的输入参数获取为unicode(非拉丁字符)
答案 0 :(得分:1)
GetModuleFileName
的用法正确。您应该使用MessageBoxW(0, filename, 0, 0);
问题出在Windows控制台上打印L"üлicä"
。
尝试在控制台上打印"üлicä"
:
int main(int argc, char *argv[])
{
DWORD count;
std::wstring str = GetCommandLineW() + (std::wstring)L"\n";
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str.c_str(), str.size(), &count, 0);
MessageBoxW(0, str.c_str(), 0, 0);
wchar_t filename[MAX_PATH];
GetModuleFileNameW(0, filename, MAX_PATH);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), filename, wcslen(filename), &count, 0);
return 0;
}
在Visual Studio中,您还可以使用_setmode
启用std::wcout/std::wcin
您还具有可选的入口点wmain(int argc, wchar_t *argv[])
,它以UTF16编码提供argv
。
main
入口点以ANSI编码(不是UTF8编码)提供argv
。与Unicode不同,ANSI可以释放信息。
答案 1 :(得分:0)
这可能与程序无关,但与控制台有关,我建议您尝试输出到文件中并检查编码是否正确。
您可以使用freopen
:
int main(int argc, char *argv[]){
freopen("output-file-name.txt", "w", stdout);
/*rest of code*/
}
如果问题仍然存在,请按照以下说明在使用_setmode(..., _O_U16TEXT)
之前尝试将Visual Studio与wcout
一起使用:https://stackoverflow.com/a/9051543/9541897
答案 2 :(得分:0)
以下是适用于Windows的示例。您必须找到正确的编译器/链接器设置,以支持MinGW上的wmain,但是它将起作用。 _setmode
可以直接将Unicode写入终端,并且只要字体支持字符就可以使用。在我的示例中,我使用了一些中文,我的字体支持:
#include <Windows.h>
#include <iostream>
#include "fcntl.h"
#include "io.h"
int wmain(int argc, wchar_t* argv[])
{
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << argv[0] << std::endl;
wchar_t filename[MAX_PATH];
GetModuleFileNameW(NULL,filename,MAX_PATH);
std::wcout << filename << std::endl;
return 0;
}
输出:
马克.exe
C:\üлicä\马克.exe
答案 3 :(得分:0)
为什么要手动键入LPWSTR
和PWSTR
? windows.h
已经为您处理了。
无论如何,如@ n.m。在注释中说,main()
的参数未在Windows上以UTF-8编码,因此使用UTF8-> UTF16转换器转换非ASCII字符将不会产生正确的输出。请使用Win32 MultiByteToWideChar()
函数来转换参数,并使用CP_ACP
作为要转换的代码页。或者,使用wmain()
代替,它以wchar_t*
而不是char*
的形式提供参数。
这将为您提供所需的数据。然后,您只需要处理将Unicode输出到控制台的问题。正如其他答案所指出的那样,Windows控制台默认情况下不支持通过std::wcout
通过UTF-16输出,因此您必须跳过一些附加的步骤才能使其正常工作(StackOverflow上还有很多其他有关该问题的问题)。