_O_WTEXT、_O_U16TEXT、_O_U8TEXT - 这些模式在 mingw 编译器中是否可能,是否有任何解决方法?

发布于 2024-12-27 11:56:05 字数 307 浏览 1 评论 0原文

#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 未在此范围内声明

这是此编译器的一个阻碍吗?

#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;
}

returns error at compilation: _O_U16TEXT was not declared in this scope

Is this a show-stopper with this compiler ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只是偏爱你 2025-01-03 11:56:05

嗯,有一个简单的解决方法:只需使用这些常量的值而不是它们的名称。例如,_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";
}

Well, there's a simple workaround: just use values of these constants instead of their names. For example, _O_U16TEXT is 0x00020000 and _O_U8TEXT is 0x00040000.

I've just confirmed that it works with _setmode using g++ 4.8.1 on Windows 10:

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

int main() {
    _setmode(_fileno(stdout), 0x00020000); // _O_U16TEXT
    std::wcout << L"Русский текст\n";
}
稚然 2025-01-03 11:56:05

对于更高的 g++ 版本(我使用的是 12.2.0),#include 包含诸如 _O_U16TEXT_O_WTEXT_O_BINARY 之类的宏。

这是整个 文件。您可以在其中看到所有及其

    #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

With a higher g++ version (I used 12.2.0), #include <fcntl.h> contains macros like _O_U16TEXT, _O_WTEXT, and _O_BINARY.

Here's the whole <fctl.h> file. You can see all macros and their values in it.

    #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
堇年纸鸢 2025-01-03 11:56:05

甚至不用理会它。

您的用户需要将其控制台的字体设置为 unicode 字体(例如 Lucida Console),否则它将不会显示任何内容。如果您的目标是东亚,那里的默认字体是 unicode 识别的,它会显示得很好,但在欧洲,您必须手动更改字体。

用户不会更改其控制台字体,因为您将其写在自述文件中。他们甚至不会阅读自述文件,他们只会看到它显示垃圾,他们会认为该程序无法运行。

另外,它是 VS 2005 中的一个全新功能,因此您需要链接 VS 2005 可再发行组件、msvcr50.dll 或更新版本(默认情况下 mingw 链接到 msvcrt.dll)。如果您不这样做,则根本不会显示文本。

我认为一个简单的管道会杀死你新的、闪亮的 unicode 文本。假设您的 exe 名为 a.exe。我很确定,a.exe | more 不会显示 unicode 文本。

Don't even bother with it.

Your user needs to set the font of his console to a unicode one (Lucida Console for example), or else it won't display anything. If you're targeting East Asia, where the default font is unicode aware, it'll display fine, but in Europe, you have to change the font manually.

User's won't change their console font because you write it in the readme. They won't even read the readme, they'll just see that it displays garbage, and they will think the program doesn't work.

Also, it's a farly new function VS 2005, so you need to link the VS 2005 redistributeable, msvcr50.dll, or newer (mingw link to msvcrt.dll by default). If you don't do this, the text, won't be displayed at all.

And I think a simple pipe will kill your new and shiny unicode text. Let's say your exe named a.exe. I'm pretty sure, that a.exe | more will NOT display unicode text.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文