使用wprintf时,为什么将©(版权符号)替换为(C)? [英] Why is © (the copyright symbol) replaced with (C) when using wprintf?

查看:186
本文介绍了使用wprintf时,为什么将©(版权符号)替换为(C)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用printfwrite打印版权符号©时,效果很好:

When I try to print the copyright symbol © with printf or write, it works just fine:

#include <stdio.h>

int main(void)
{
    printf("©\n");
}

#include <unistd.h>

int main(void)
{
    write(1, "©\n", 3);
}

输出:

©

但是当我尝试使用wprintf打印它时,我得到了(C):

But when I try to print it with wprintf, I get (C):

#include <stdio.h>
#include <wchar.h>

int main(void)
{
    wprintf(L"©\n");
}

输出:

(C)

但是,当我向setlocale添加呼叫时,此问题已解决:

It's fixed when I add a call to setlocale, though:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_ALL, "");
    wprintf(L"©\n");
}

输出:

©

为什么出现原始行为,为什么在调用setlocale时会得到解决?此外,此转换在哪里进行?以及如何使setlocale之后的行为成为默认行为?

Why is the original behavior present and why is it fixed when I call setlocale? Additionally, where does this conversion take place? And how can I make the behavior after setlocale the default?

编译命令:

gcc test.c

locale:

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

echo $LC_CTYPE:


uname -a:

Linux penguin 4.19.79-07511-ge32b3719f26b #1 SMP PREEMPT Mon Nov 18 17:41:41 PST 2019 x86_64 GNU/Linux

file test.c(所有示例都相同):

file test.c (same on all of the examples):

test.c: C source, UTF-8 Unicode text

gcc --version:

gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 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.

/lib/x86_64-linux-gnu/libc-2.24.so(glibc版本):

GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 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.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

cat /etc/debian_version:

9.12

推荐答案

新进程不会自动继承调用进程的语言环境.

The locale of the calling processes is not automatically inherited by the new process.

程序首次启动时,它位于C语言环境中. setlocale(3)手册页显示以下内容:

When the program first starts up, it is in the C locale. The man page for setlocale(3) says the following:

在启动主程序时,选择了可移植的"C"语言环境 默认情况下.可以通过调用以下程序使程序可移植到所有地区:

On startup of the main program, the portable "C" locale is selected as default. A program may be made portable to all locales by calling:

setlocale(LC_ALL, "");

...

语言环境"C"或"POSIX"是可移植的语言环境;其LC_CTYPE部分对应于7位ASCII字符集.

The locale "C" or "POSIX" is a portable locale; its LC_CTYPE part corresponds to the 7-bit ASCII character set.

因此,如输出所示,任何多字节/非ASCII字符都将转换为一个或多个ASCII字符.

So any multibyte / non-ASCII character is converted into one or more ASCII characters as the output shows.

区域设置可以设置如下:

The locale can be set as follows:

setlocale(LC_ALL, "");

LC_ALL标志指定更改所有与语言环境相关的变量.语言环境的空字符串表示根据相关环境变量设置语言环境.完成此操作后,您应该会看到外壳语言环境的字符.

The LC_ALL flag specifies changing all locale-related variables. An empty string for the locale means to set the locale according to the relevant environment variables. Once this is done, you should see the characters for your shell's locale.

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main()
{
    char *before = setlocale(LC_ALL, NULL);
    setlocale(LC_ALL, "");
    char *after = setlocale(LC_ALL, NULL);

    wprintf(L"before locale: %s\n", before);
    wprintf(L"after locale: %s\n", after);
    wprintf(L"©\n");
    wprintf(L"\u00A9\n");
    return 0;
}

输出:

before locale: C
after locale: en_US.utf8
©
©

这篇关于使用wprintf时,为什么将©(版权符号)替换为(C)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆