提问人:clearcom0 提问时间:11/28/2022 更新时间:11/29/2022 访问量:88
如何使用 gnome 终端从 c 控制台应用程序打印欧元符号
How to print euro sign from c console app using gnome terminal
问:
我正在尝试通过 c 控制台应用程序在 Gnome Terminal 应用程序的控制台上打印欧元符号。我的代码是:
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>
#include <locale.h>
int main (int argc, char* argv[]) {
setlocale(LC_CTYPE,"UTF-8");
wchar_t w_char1 = '€';
wprintf(L"%x\n", w_char1);
wprintf(L"%c\n", w_char1);
wchar_t w_char2=0xE282AC;
wprintf(L"%x\n", w_char2);
wprintf(L"%c\n", w_char2);
wchar_t w_char3='\u20AC';
wprintf(L"%x\n", w_char3);
wprintf(L"%c\n", w_char3);
}
这将在控制台上打印以下内容:
e282ac
e282ac
e282ac
我已经尝试了使用和不使用 setlocale 的方法。在 Gnome 终端首选项的“兼容性”下,“编码”设置为 。Unicode -- UTF-8
知道为什么欧元符号不打印吗?
答:
这没有一个完整的解决方案,但我认为它提供了一些有用的解决方案指针。现在是午夜,我需要上床睡觉。
wprintf()
的 POSIX 手册页指示您需要在转换说明符之前使用修饰符:l
c
l
(埃尔)
指定后面的 、 、 、 或 转换说明符应用于 或 参数;以下转换说明符适用于指向参数的指针;以下转换说明符适用于参数;以下转换说明符适用于指向参数的指针;或对后面的 、 、 、 、 或 转换说明符没有影响。d
i
o
u
x
X
long
unsigned long
n
long
c
wint_t
s
wchar_t
a
A
e
E
f
F
g
G
然后是一个问题,即 a 是否转换为 a——它可能确实如此。wchar_t
wint_t
我遇到了一个问题,我必须编译该问题以抑制错误,例如:-Wno-multichar
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -fno-common wprintf37.c -o wprintf37
wprintf37.c: In function ‘main’:
wprintf37.c:9:23: error: multi-character character constant [-Werror=multichar]
9 | wchar_t w_char1 = '€';
| ^~~
wprintf37.c:15:21: error: multi-character character constant [-Werror=multichar]
15 | wchar_t w_char3='\u20AC';
| ^~~~~~~~
cc1: all warnings being treated as errors
$
您还应该检查该操作是否有效——它不适合我。我使用并检查了它;这奏效了。我正在使用 Mac,并且已在环境中设置。我仍然没有看到欧元符号。setlocale()
setlocale(LC_ALL, "")
LANG=en_us.UTF-8
嗯......
当事情失败时,调试的规则之一是“检查每个可以报告错误的函数”。此代码执行此操作,结果如下所示:
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
static void err_warn(int rv, const char *msg)
{
fwprintf(stderr, L"%s: rv = %d (%d) %s\n", msg, rv, errno, strerror(errno));
errno = 0;
clearerr(stdout);
}
int main(void)
{
if (setlocale(LC_ALL, "") == NULL)
{
fprintf(stderr, "failed to set the default locale\n");
return 1;
}
int rv;
wchar_t w_char1 = '€';
if ((rv = wprintf(L"%x\n", w_char1)) < 0)
err_warn(rv, "wprintf - 1");
if ((rv = wprintf(L"C1 = %lc\n", w_char1)) < 0)
err_warn(rv, "wprintf - 2");
putwchar(L'\n');
fflush(stdout);
wchar_t w_char2=0xE282AC;
if ((rv = wprintf(L"%x\n", w_char2)) < 0)
err_warn(rv, "wprintf - 3");
if ((rv = wprintf(L"C2 = %lc\n", w_char2)) < 0)
err_warn(rv, "wprintf - 4");
putwchar(L'\n');
fflush(stdout);
wchar_t w_char3='\u20AC';
if ((rv = wprintf(L"%x\n", w_char3)) < 0)
err_warn(rv, "wprintf - 5");
if ((rv = wprintf(L"C3 = %lc\n", w_char3)) < 0)
err_warn(rv, "wprintf - 6");
putwchar(L'\n');
fflush(stdout);
char s[] = "€";
if ((rv = wprintf(L"S = %s\n", s)) < 0)
err_warn(rv, "wprintf - 7");
return 0;
}
输出(在我的 Mac 上):
e282ac
wprintf - 2: rv = -1 (92) Illegal byte sequence
C1 =
e282ac
wprintf - 4: rv = -1 (92) Illegal byte sequence
C2 =
e282ac
wprintf - 6: rv = -1 (92) Illegal byte sequence
C3 =
S = €
请注意,错误报告函数会清除标准输出 () 上的错误状态并重置为零 — 没有标准 C 库函数这样做。在我打电话之前,所有操作都报告了第一次失败。clearerr(stdout)
errno
clearerr()
我认为可能有必要使用或类似的东西。查看 §6.4.4.4 字符常量和 §6.4.5 字符串文字以获取更多想法。u8'€'
二十四小时后。
此代码运行良好:
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
static void err_warn(int rv, const char *msg)
{
fwprintf(stderr, L"%s: rv = %d (%d) %s\n", msg, rv, errno, strerror(errno));
errno = 0;
clearerr(stdout);
}
int main(void)
{
if (setlocale(LC_ALL, "") == NULL)
{
fprintf(stderr, "failed to set the default locale\n");
return 1;
}
int rv;
/* This now works */
wchar_t w_char1 = L'€';
if ((rv = wprintf(L"%x\n", w_char1)) < 0)
err_warn(rv, "wprintf - 1");
if ((rv = wprintf(L"C1 = %lc\n", w_char1)) < 0)
err_warn(rv, "wprintf - 2");
putwchar(L'\n');
fflush(stdout);
/* Still failing */
wchar_t w_char2 = 0xE282AC;
if ((rv = wprintf(L"%x\n", w_char2)) < 0)
err_warn(rv, "wprintf - 3");
if ((rv = wprintf(L"C2 = %lc\n", w_char2)) < 0)
err_warn(rv, "wprintf - 4");
putwchar(L'\n');
fflush(stdout);
/* This works */
wchar_t w_char3 = 0x20AC;
if ((rv = wprintf(L"%x\n", w_char3)) < 0)
err_warn(rv, "wprintf - 5");
if ((rv = wprintf(L"C2 = %lc\n", w_char3)) < 0)
err_warn(rv, "wprintf - 6");
putwchar(L'\n');
fflush(stdout);
/* This now works */
wchar_t w_char4 = L'\u20AC';
if ((rv = wprintf(L"%x\n", w_char4)) < 0)
err_warn(rv, "wprintf - 7");
if ((rv = wprintf(L"C3 = %lc\n", w_char4)) < 0)
err_warn(rv, "wprintf - 8");
putwchar(L'\n');
fflush(stdout);
char s[] = "€";
if ((rv = wprintf(L"S = %s\n", s)) < 0)
err_warn(rv, "wprintf - 9");
return 0;
}
它给出的输出是:
20ac
C1 = €
e282ac
wprintf - 4: rv = -1 (92) Illegal byte sequence
C2 =
20ac
C2 = €
20ac
C3 = €
S = €
请注意,成功的值都包含 U+20AC。
评论
printf("%c%c%c\n", 0xE2, 0x82, 0xAC);
char
locale -a