【问题标题】:Where to get _fileno and _O_U16TEXT?从哪里获得 _fileno 和 _O_U16TEXT?
【发布时间】:2019-07-01 19:01:09
【问题描述】:

我正在尝试打印文本“Ääkkösiä ruutuun”。用 c++ 进行控制台。我有 Windows 7 并且正在使用 Code::Blocks 编辑器。搜索该主题,我发现这些行可能会有所帮助

_setmode(_fileno(stdout), _O_U16TEXT);
wstring s{L"Ääkkösiä ruutuun."};
wcout<<s<<endl;

但是当我尝试编译它时,我得到了错误:_fileno is not declared in this scope.

我拥有所有这些包括:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stdexcept>
#include <cmath>
#include <sstream>
#include <fstream>
#include <codecvt>
#include <locale>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <cstdio>
#include <ostream>

我错过了什么?

另外,我尝试过的另一件事是语言环境,但是没有找到 locale::empty!为什么我的 c++ 里面什么都没有?

编辑 这是我的程序现在正在做什么的图片。

它只打印第一个字母 (Ä)。其余的会怎样?

好的,似乎 setmode 设置它以便只打印一个字母。 (即使尝试使用多个命令打印普通文本,也只会产生一个字母。)没有它,斯堪的纳维亚字母就无法正确打印,想。它们看起来像这样:

【问题讨论】:

  • 根据微软的说法,_fileno&lt;stdio.h&gt; 中定义。根据 IBM 和其他公司的说法,它是 fileno,没有定义下划线。
  • 我都试过了,都没有找到。顺便说一句,为什么在 stdio 中需要 .h,因为例如在 "#include ? 中不需要
  • 我认为你需要看看你的开发环境是如何配置的。听起来您的包含路径未定义。至于&lt;stdio&gt;&lt;stdio.h&gt;,嗯,前者是标准的,后者应该也可以工作。
  • 您不需要fileno(stdout)。在unistd.h 中有一个STDOUT_FILENO(通常等于1)。
  • @Vovanium 好的,找到了。但是_O_U16TEXT呢?

标签: c++ windows console-application utf scandir


【解决方案1】:

您找到的答案是针对 Visual Studio,而不是 Code::Blocks。

虽然 C 标准指定了 &lt;stdio.h&gt; 中应该包含的内容,但它只指定了最小值。实现者可以添加他们自己的函数,并且应该使用_(下划线前缀)这样做。这就是为什么您不应该使用该前缀的原因。你不知道你会打破什么。 Microsoft 使用正确的前缀清楚地表明了他们的非标准扩展。

答案标记为C++,但是C++从C继承了&lt;stdio.h&gt;的内容。

【讨论】:

  • 它确实破坏了一些东西,因为它只打印出一个字母。幸好不是永久的,因为注释掉 setmode-call 会将其恢复为乱码的 scandis,但至少它会打印所有内容。好的,所以现在我正在尝试搜索 Code::Blocks 解决方案。我只是不知道该用什么词。有人会认为这是一个解决了仅打印 unicode 内容的问题。
  • @ploosu2: Unicode 人自己似乎被添加表情符号占据了。我不能为此完全责怪微软或 Code::Blocks。
  • @ploosu2:如果您愿意设置 Code::Blocks 以使用 mingw-w64 工具链,您将拥有_fileno。或者,您可以自己定义(检查在 cmets 到 OP 中标记为重复的问题)。
【解决方案2】:

线

setlocale(LC_CTYPE, ".OCP");

有效!

一个完整的例子:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <fstream>

using namespace std;

wstring readFile(const char* filename) {
    wifstream wif(filename);
    locale myLoc("");
    //locale utf8_locale(locale(), new gel::stdx::utf8cvt<true>);
    wif.imbue(myLoc);
    basic_stringstream<wchar_t> wss;
    wss << wif.rdbuf();
    return wss.str();
}

int main() {
    setlocale(LC_CTYPE, ".OCP");
    wstring contents = readFile("test.txt");
    wcout<<L"Does anything get printed out at all???"<<endl;
    //wcout <<contents<<endl;
    wstring s{L"Ääkkösiä ruutuun."};
    wcout<<s<<endl;
    wcout<<L"Näkyykö äkköset?"<<endl;
    return 0;
}

但是,从文件 (utf-8) 读取的文本仍然无法正确打印。 应该是

嘿!
Täällä 上 kaksi riviä。

那里出了问题。

输出:

【讨论】:

  • 这将您限制在 OEM 代码页中,如果它像 MSVC 一样,则会对控制台输出代码页进行双重转换,这也恰好默认为 OEM。在这种情况下,只有 Windows 10 支持 UTF-8,这是测试版而不是默认配置。在 Windows 7 中,它将是一个遗留代码页,非亚洲语言环境限制为大约 250 个字符。如果您的 C/C++ 库无法使用控制台的 Unicode API,您可以使用 UTF-16LE 文本直接调用 WriteConsoleW
  • setlocale() 所做的事情与您在问题中所做的事情完全不同。请参阅我的回答 here,以及我在您的问题中尽可能重复链接的问题。
猜你喜欢
  • 2021-12-31
  • 2020-09-21
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
相关资源
最近更新 更多