【发布时间】: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"<%i> points to <%ls>"来缩小问题的范围。 -
超级有趣,我得到
<4> points to < Smurfs> -
如果您运行代码并将输出重定向到文件
a.out > t.bin,文件转储会显示什么? -
部分混合是有广泛支持的诅咒,t.bin 是空的
-
听起来 Windows 用字节顺序标记做了一些奇怪的事情(U+FEFF 用作字节顺序标记字符)。