【问题标题】:vswprintf keeps prefixing a Byte Order Mark charactervswprintf 不断为字节顺序标记字符添加前缀
【发布时间】:2018-10-18 13:53:33
【问题描述】:

我仍然是 C 的新手,甚至是 C 中的宽字符的新手。

下面的代码应该显示

4 points to Smurfs

但它显示

4 points to Smurfs

在 gdb 中我看到这个:

(gdb) p buffer
$1 = L" 4 points to  Smurfs",

但是当我从控制台复制粘贴时,空格神奇地消失了:

(gdb) p buffer
$1 = L"4 points to Smurfs",

另外,buffer[0] 根据gdb 包含此内容: 65279 L' '

显然,有问题的字符  是 Unicode 字符“零宽度无间隔空格”(U+FEFF)。我重新输入了代码,确保我没有输入这个。我不知道这是从哪里来的。我还根据https://stackoverflow.com/a/9691839/7602 在记事本中打开了代码,那里没有多余的字符。

我不在乎 ncurses 是否会停止将其显示为空格。

代码(大幅缩减):

#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <wchar.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#define NCURSES_WIDECHAR 1
#include <ncursesw/ncurses.h>

#include "types.h"
#include "defines.h"
#include "externs.h"

WINDOW * term;

/*row column color n arguments */
void rccn(int row, int col, const wchar_t *fmt, ...)
{
    wchar_t buffer[80];
    int size;

    va_list args;
    va_start(args, fmt);
    size = vswprintf(buffer, 80, fmt, args);
    va_end( args );

    if(size >= 80){
        mvaddwstr(row, col, L"Possible hacker detected!");
    }else{
        mvaddwstr(row, col, buffer);
    }
}


int main(void)
{
    int ch;
    setlocale(LC_ALL,"");
    term = initscr();

    rccn(1,1,L"%i points to %ls",4,L"Smurfs");
    ch = getch();

    return EXIT_SUCCESS;
}

问题“消失”了 rccn(1,1,L"%i points to %ls",4,L"Smurfs"+1);

好像常量的宽编码在前面添加了那个字符..

【问题讨论】:

  • 也许改成L"&lt;%i&gt; points to &lt;%ls&gt;" 来缩小问题的范围。
  • 超级有趣,我得到&lt;4&gt; points to &lt; Smurfs&gt;
  • 如果您运行代码并将输出重定向到文件a.out &gt; t.bin,文件转储会显示什么?
  • 部分混合是有广泛支持的诅咒,t.bin 是空的
  • 听起来 Windows 用字节顺序标记做了一些奇怪的事情(U+FEFF 用作字节顺序标记字符)。

标签: c printf


【解决方案1】:

找到了..

我遵循了一个建议添加此编译器标志的教程: -fwide-exec-charset=utf-32

我的代码根本没有在 Cygwin 上运行,我读到 Windows 以 utf-16 为中心,所以我删除了那个编译器标志,它开始在 Cygwin 上运行。

然后出于好奇,我删除了 Raspbian 上的编译器标志,它现在也可以正常工作,不再有字节顺序标记。

【讨论】:

    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 2020-04-28
    • 2015-06-03
    • 2014-06-16
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2010-09-30
    相关资源
    最近更新 更多