【问题标题】:Unicode strings containing unicode characters are always empty包含 Unicode 字符的 Unicode 字符串始终为空
【发布时间】:2020-12-19 22:12:20
【问题描述】:

我正在使用 -municode -DUNICODE -D_UNICODE 标志进行编译,并使用_tmain 启用Unicode 支持。

但是当我对任何包含 unicode 字符的 TCHAR 数组执行操作时,字符串最终会在该字符所在的位置被截断。

例如:

TCHAR buffer[255];
wcscpy(buffer, L"test-");
wcscat(buffer, L"Азәрбајҹан");
/* buffer now contains "test-" */

我的实际用例是检索用户名,如果它包含特殊字符,则无论是来自 GetEnvironmentVariableGetUsername 还是像上面这样的硬编码字符串,最终都会为空。

编辑:

这是一个完整的最小可重现示例:

gcc -o error.exe error.c -municode下编译:

gcc.exe (Rev3, Built by MSYS2 project) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

代码:

#define _UNICODE
#define UNICODE

#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, TCHAR* argv[]) {
    FILE* fp;
    TCHAR buffer[255];

    _tcscpy(buffer, _T("test-"));
    _tcscat(buffer, _T("Азәрбајҹан"));
    _tprintf(_T("Length: %d, Content: %ls\n"), _tcslen(buffer), buffer);

    fp = _tfopen(_T("test.txt"), _T("w"));
    _ftprintf(fp, _T("%ls"), buffer);
    fclose(fp);
    return 0;
}

此示例打印 15 test- 并将 test- 放入 test.txt。

【问题讨论】:

  • 您列出的编译器标志是指 Windows API 宏,它们与 wcscpy 或 C 标准规定的其他功能无关
  • 我不反对 OP 应该编辑以提供minimal reproducible example,如果没有其他原因来显示#includes,并使用main() 的签名,但不明白为什么不赞成。从问题变得活跃起,OP 就一直积极参与其中,与我今天在该网站上看到的许多投票赞成的问题相比,问题显示出更多的努力和研究。
  • 我无法让它工作。这个 TCHAR 垃圾不在 C 标准之内。扔了它。在内部使用 UTF-8 并在需要时进行转换。 docs.microsoft.com/en-us/windows/win32/api/stringapiset/… 我倒霉的时候就是这样做的,不得不为 Windows 写点东西。如果你要允许 UTF-8,你无论如何都不会为 ANSI 编译所以......
  • 源文件编码是什么? gcc 可能希望它是 UTF-8。 Microsoft 假定 ANSI 编码没有/utf-8 编译器开关,或使用带 BOM 编码的 UTF-8。

标签: c windows unicode mingw


【解决方案1】:

对于宽字符,我通常使用wchar_t

如果这是一个选项,你可以使用类似的东西:

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

int _tmain() {

#ifdef UNICODE
    _setmode(_fileno(stdin), _O_WTEXT);
    _setmode(_fileno(stdout), _O_WTEXT);
#endif

    wchar_t buffer[255];

    wcscpy(buffer, L"test-");
    wcscat(buffer, L"Азәрбајҹан");
    wprintf(L"%s\n", buffer);

    return 0;
}

输出:

启用 VS 2019 with MSVCUse Unicode Character Set

gcc version 9.2.0 (tdm64-1)

【讨论】:

  • 我在我的环境中正是这样做的(使用带有 GNU GCC 编译器的 Code::Blocks,它输出的正是 OP 显示的内容,即test-
  • @ryyker, windows?
  • @ryyker,在 VS2019 中,您可以将设置更改为多字节或 Unicode,我使用多字节,但 Unicode 似乎也可以工作。我知道你可以在代码中定义它,但我不记得如何了。
  • @ryyker "btw WCHAR 只是一个宏,对于没有定义UNICODE 的环境定义为char,对于那些定义为wchar_t 的环境 i>”——这根本不是真的。 WCHAR 在所有系统上一直并且一直被定义为 wchar_t。您正在考虑的是 TCHAR,它确实映射到 wchar_tchar 基于 UNICODE 定义的存在或缺失。
  • @anastaciu TDM64 是 mingw-w64 的构建
猜你喜欢
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 2020-05-06
  • 2011-01-28
  • 2015-06-09
  • 2021-07-16
相关资源
最近更新 更多