c++ _O_WTEXT,_O_U16TEXT,_O_U8TEXT -这些模式在mingw编译器中可能吗?有什么变通方法吗?

snvhrwxg  于 2023-04-08  发布在  其他
关注(0)|答案(3)|浏览(185)
#include <fcntl.h>
#include <io.h>
#include <stdio.h>

int main(void) {
  _setmode(_fileno(stdout), _O_U16TEXT);
  wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
  return 0;
}

编译时返回错误:_O_U16TEXT was not declared in this scope
这是一个显示塞与此编译器?

syqv5f0l

syqv5f0l1#

有个简单的解决办法只需使用这些常量的值而不是它们的名称。例如,_O_U16TEXT0x00020000_O_U8TEXT0x00040000
我刚刚确认它可以在Windows 10上使用g++ 4.8.1与_setmode一起使用:

#include <iostream>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>

int main() {
    _setmode(_fileno(stdout), 0x00020000); // _O_U16TEXT
    std::wcout << L"Русский текст\n";
}
t2a7ltrp

t2a7ltrp2#

在更高的g++版本(我使用的是12.2.0)中,#include <fcntl.h>包含_O_U16TEXT_O_WTEXT_O_BINARY等宏。
这是整个<fctl.h>文件。您可以在其中看到所有macros及其values

#include <crtdefs.h>
    
    #include <io.h>
    
    #ifndef _INC_FCNTL
    #define _INC_FCNTL
    
    #define _O_RDONLY 0x0000
    #define _O_WRONLY 0x0001
    #define _O_RDWR 0x0002
    #define _O_APPEND 0x0008
    #define _O_CREAT 0x0100
    #define _O_TRUNC 0x0200
    #define _O_EXCL 0x0400
    #define _O_TEXT 0x4000
    #define _O_BINARY 0x8000
    #define _O_WTEXT 0x10000
    #define _O_U16TEXT 0x20000
    #define _O_U8TEXT 0x40000
    #define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR)
    
    #define _O_RAW _O_BINARY
    #define _O_NOINHERIT 0x0080
    #define _O_TEMPORARY 0x0040
    #define _O_SHORT_LIVED 0x1000
    
    #define _O_SEQUENTIAL 0x0020
    #define _O_RANDOM 0x0010
    
    #if !defined(NO_OLDNAMES) || defined(_POSIX)
    #define O_RDONLY _O_RDONLY
    #define O_WRONLY _O_WRONLY
    #define O_RDWR _O_RDWR
    #define O_APPEND _O_APPEND
    #define O_CREAT _O_CREAT
    #define O_TRUNC _O_TRUNC
    #define O_EXCL _O_EXCL
    #define O_TEXT _O_TEXT
    #define O_BINARY _O_BINARY
    #define O_RAW _O_BINARY
    #define O_TEMPORARY _O_TEMPORARY
    #define O_NOINHERIT _O_NOINHERIT
    #define O_SEQUENTIAL _O_SEQUENTIAL
    #define O_RANDOM _O_RANDOM
    #define O_ACCMODE _O_ACCMODE
    #endif
    #endif
esyap4oy

esyap4oy3#

别费心了。
您的用户需要将其控制台的字体设置为unicode字体(例如Lucida控制台),否则它将不会显示任何内容。如果您的目标是东亚,那里的默认字体是unicode,它将显示良好,但在欧洲,您必须手动更改字体。
用户不会因为你在自述文件中写了字体而改变他们的控制台字体,他们甚至不会读自述文件,他们只会看到它显示垃圾,他们会认为程序不工作。
另外,这是VS 2005的一个新功能,所以你需要链接VS 2005可再发行版,msvcr50.dll或更新的版本(默认情况下mingw链接到msvcrt.dll)。
我认为一个简单的管道会杀死你的新的和闪亮的unicode文本。让我们说你的exe命名为a.exe。我很肯定,a.exe | more将不会显示unicode文本。

相关问题