putwchar() 无法显示 wchar_t 变量
putwchar() can't diplay a wchar_t variable
为什么 printf() 可以显示 é
(\u00E9
int UTF-16) 而 putwchar() 不能?
让 putwchar 正确显示 é
的正确语法是什么?
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "fr_FR.utf8");
printf("%C\n", wc);
putwchar((wchar_t)wc);
putchar('\n');
return 0;
}
环境
- OS : openSUSE Leap 42.1
- 编译器:gcc 版本 4.8.5 (SUSE Linux)
- 终端:终结者
- 终端编码:UTF-8
- Shell : zsh
- CPU : x86_64
Shell环境:
env | grep LC && env | grep LANG
LC_CTYPE=fr_FR.utf8
LANG=fr_FR.UTF-8
GDM_LANG=fr_FR.utf8
编辑
在 :
wint_t wc = L'\u00E9'
setlocale(LC_CTYPE, "");
输出:
C3 A9 0A E9 0A
在:
wint_t wc = L'\xc3a9';
setlocale(LC_CTYPE, "");
输出:
EC 8E A9 0A A9 0A
问题是您的 setlocale()
呼叫失败。如果你检查结果,你会看到。
if( !setlocale(LC_CTYPE, "fr_FR.utf8") ) {
printf("Failed to set locale\n");
return 1;
}
问题是 fr_FR.utf8
不是正确的语言环境名称。相反,请使用 LANG
格式:fr_FR.UTF-8
.
if( !setlocale(LC_CTYPE, "fr_FR.UTF-8") ) {
printf("Failed to set locale\n");
return 1;
}
区域名称是您系统上安装的任何名称,可能在 /usr/share/locale/
中。或者您可以使用 locale -a
.
获取列表
您很少想对语言环境进行硬编码。通常你想使用环境指定的任何东西。为此,请将 ""
作为区域设置传递给程序,然后程序会计算出来。
if( !setlocale(LC_CTYPE, "") ) {
printf("Failed to set locale\n");
return 1;
}
您不能在同一个流中混合使用宽字符和字节 input/output 函数(printf 是一个字节输出函数,无论它是否包含宽字符格式)。流的方向只能用 freopen
重置,这必须在调用 byte-oriented putchar
函数之前再次完成。
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "");
printf("%lc\n", wc);
freopen(NULL, "w", stdout);
putwchar((wchar_t)wc);
freopen(NULL, "w", stdout);
putchar('\n');
return 0;
}
方向只能通过重新打开流来设置这一事实表明这不是为了简单地完成,大多数程序应该只使用一种输出。 (即 wprintf/putwchar 或 printf/putchar,如果需要打印宽字符,则使用 printf 或 wctomb)
为什么 printf() 可以显示 é
(\u00E9
int UTF-16) 而 putwchar() 不能?
让 putwchar 正确显示 é
的正确语法是什么?
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "fr_FR.utf8");
printf("%C\n", wc);
putwchar((wchar_t)wc);
putchar('\n');
return 0;
}
环境
- OS : openSUSE Leap 42.1
- 编译器:gcc 版本 4.8.5 (SUSE Linux)
- 终端:终结者
- 终端编码:UTF-8
- Shell : zsh
- CPU : x86_64
Shell环境:
env | grep LC && env | grep LANG
LC_CTYPE=fr_FR.utf8
LANG=fr_FR.UTF-8
GDM_LANG=fr_FR.utf8
编辑
在 :
wint_t wc = L'\u00E9'
setlocale(LC_CTYPE, "");
输出:
C3 A9 0A E9 0A
在:
wint_t wc = L'\xc3a9';
setlocale(LC_CTYPE, "");
输出:
EC 8E A9 0A A9 0A
问题是您的 setlocale()
呼叫失败。如果你检查结果,你会看到。
if( !setlocale(LC_CTYPE, "fr_FR.utf8") ) {
printf("Failed to set locale\n");
return 1;
}
问题是 fr_FR.utf8
不是正确的语言环境名称。相反,请使用 LANG
格式:fr_FR.UTF-8
.
if( !setlocale(LC_CTYPE, "fr_FR.UTF-8") ) {
printf("Failed to set locale\n");
return 1;
}
区域名称是您系统上安装的任何名称,可能在 /usr/share/locale/
中。或者您可以使用 locale -a
.
您很少想对语言环境进行硬编码。通常你想使用环境指定的任何东西。为此,请将 ""
作为区域设置传递给程序,然后程序会计算出来。
if( !setlocale(LC_CTYPE, "") ) {
printf("Failed to set locale\n");
return 1;
}
您不能在同一个流中混合使用宽字符和字节 input/output 函数(printf 是一个字节输出函数,无论它是否包含宽字符格式)。流的方向只能用 freopen
重置,这必须在调用 byte-oriented putchar
函数之前再次完成。
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
wint_t wc = L'\u00E9';
setlocale(LC_CTYPE, "");
printf("%lc\n", wc);
freopen(NULL, "w", stdout);
putwchar((wchar_t)wc);
freopen(NULL, "w", stdout);
putchar('\n');
return 0;
}
方向只能通过重新打开流来设置这一事实表明这不是为了简单地完成,大多数程序应该只使用一种输出。 (即 wprintf/putwchar 或 printf/putchar,如果需要打印宽字符,则使用 printf 或 wctomb)