【问题标题】:C++ wchart_t warning: character constant too long for its typeC++ wchart_t 警告:字符常量对于它的类型来说太长了
【发布时间】:2017-03-26 06:04:42
【问题描述】:

//更新1:

代码块 16.01
GCC 4.9.2
视窗 10

我正在努力理解:

  1. wchar_t 有什么用?
  2. char16_t 和 wchar_t 有什么区别?
    我知道 char16_t 的大小保证为 16 位,但在这种特殊情况下,它们的大小相同。
  3. 每种 char 类型的正确文字是什么?

计划目标:

  • 打印 U+0000 到 U+FFFF 范围内的所有 Unicode 字符。

//结束更新1

当我编译以下代码时:

#include <iostream>

int main(void)

{
    std::cout << sizeof(wchar_t) << "\n";
    for (wchar_t ch = u'\u0000'; ch <= u'\uffff'; ++ch)
        std::wcout << " " << ch;

    std::cout << "\n\n\n";
}

我在 for 语句的行上收到以下警告:“字符常量对于它的类型来说太长了”。

我运行了这个程序,得到了这个: .

我搜索了网络,我能找到的只是 wchar_t 大小是实现定义的,但即便如此,它在我的系统上还是 2 个字节。我认为它已经足够大了。

Q1:为什么我收到警告?
Q2:为什么输出中有几个字符?我预计会有数千个。

【问题讨论】:

  • 这段代码应该做什么?
  • 为什么不改用 char16_t 呢?
  • 什么编译器、版本和操作系统?
  • u'\uf00d' 用于char16_t 常量,将L'\uf00d' 用于wchar_t 常量。
  • 另外,如果每个wchar_t 值都小于或等于\uffff,您的测试可能会失败。

标签: c++ types wchar-t


【解决方案1】:

以下内容可能更符合预期,将 U+0000 到 U+FFFF 的每个可打印代码点显示为 Unicode。请务必将您的控制台字体设置为 Unicode 字体。

#include <cstdlib>
#include <cwctype>
#include <locale>
#include <iostream>

#if _WIN32 || _WIN64
// Windows needs a little non-standard magic for this to work.
#include <io.h>
#include <fcntl.h>
#include <locale.h>
#endif

using std::wint_t;
using std::iswprint;

void init_locale(void)
// Does magic so that wcout can work.
{
#if _WIN32 || _WIN64
  // Windows needs a little non-standard magic.
  constexpr char cp_utf16le[] = ".1200";
  setlocale( LC_ALL, cp_utf16le );
  _setmode( _fileno(stdout), _O_WTEXT );
#else
  // The correct locale name may vary by OS, e.g., "en_US.utf8".
  constexpr char locale_name[] = "";
  std::locale::global(std::locale(locale_name));
  std::wcout.imbue(std::locale());
#endif
}

int main(void)
{
    init_locale();

    for ( unsigned long i = 0; i < 0x10000UL; ++i )
      if (iswprint(static_cast<wint_t>(i)))
        std::wcout << static_cast<wchar_t>(i);

    std::wcout << std::endl;

    return EXIT_SUCCESS;
}

【讨论】:

  • 谢谢@Davislor。这正是我想要做的,但是,我尝试了你的代码,我得到了这些错误:|23|error: 'stdout' was not declared in this scope| 相同的 _fileno_O_WTEXT 在同一行。
  • 哪个编译器和操作系统?
  • 这段代码已经在 Linux 和 Windows 上的 g++ 和 clang++ 以及 Visual Studio 2017 上进行了测试。听起来好像有一些环境(CygWin?)设置了_WIN32_WIN64但不提供 MS 库头文件。如果是这样,我可能需要更新该测试以检查 !__GLIBCXX__!_LIBCPP_VERSION
  • 我在VS2017上运行代码成功。使用正确的代码页和正确的控制台字体,我可以看到我一直在寻找的内容。但是,我还不知道为什么 codeblock/gcc 不能这样做。此外,我尝试在代码中使用 unicode 文字,例如
  • 如果您将源文件保存为带有字节顺序标记的 UTF-8,那么每个现代编译器都应该能够正确读取它。然后,您可以在字符串文字中使用任何字符,例如 L"étant donné" 至少我经常使用的一个编译器在使用除此之外的任何其他编码时都会遇到问题。
【解决方案2】:

当我运行这段代码时,它运行良好:

int main(void)

{
    std::cout << sizeof(char16_t) << "\n";
    for (char16_t ch = u'\u0000'; ch <= u'\uffff'; ++ch)
        std::wcout << " " << static_cast<char>(ch);

    std::cout << "\n\n\n";
}

【讨论】:

  • 谢谢@felipe-lopez。但是,我用相同的输出得到了相同的结果。此外,警告仍然存在。为了更清楚,我更新了问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-26
相关资源
最近更新 更多