“可能吗?”;强迫;C程序中的UTF-8?

“可能吗?”;强迫;C程序中的UTF-8?,c,encoding,utf-8,character-encoding,C,Encoding,Utf 8,Character Encoding,通常,当我希望我的程序使用UTF-8编码时,我会编写setlocale(LC_ALL,”)。但今天我发现它只是将locate设置为环境的默认区域设置,我不知道环境是否默认使用UTF-8 我想知道有没有办法强制字符编码为UTF-8?还有,有没有办法检查我的程序是否使用UTF-8?试试: setlocale(LC_ALL, "en_US.UTF-8"); 您可以在终端中运行locale-a,以获得您的系统支持的区域设置的完整列表(“en_US.UTF-8”应得到大多数/所有UTF-8支持系统的支持

通常,当我希望我的程序使用UTF-8编码时,我会编写
setlocale(LC_ALL,”)。但今天我发现它只是将locate设置为环境的默认区域设置,我不知道环境是否默认使用UTF-8

我想知道有没有办法强制字符编码为UTF-8?还有,有没有办法检查我的程序是否使用UTF-8?

试试:

setlocale(LC_ALL, "en_US.UTF-8");
您可以在终端中运行
locale-a
,以获得您的系统支持的区域设置的完整列表(“en_US.UTF-8”应得到大多数/所有UTF-8支持系统的支持)

编辑1(交替拼写)

Lee在评论中指出,有些系统有另一种拼写,
“en_US.utf8”
(这让我很惊讶,但我们每天都在学习新的东西)

由于
setlocale
失败时返回NULL,因此可以链接这些调用:

if(!setlocale(LC_ALL, "en_US.UTF-8") && !setlocale(LC_ALL, "en_US.utf8"))
   printf("failed to set locale to UTF-8");
编辑2(了解我们是否使用UTF-8)

要确定区域设置是否设置为UFT-8(在尝试设置之后),可以检查返回值(
NULL
表示调用失败)或检查使用的区域设置

备选案文1:

char * result;
if((result = setlocale (LC_ALL, "en_US.UTF-8")) == NULL)
   printf("failed to set locale to UTF-8");
备选案文2:

setlocale (LC_ALL, "en_US.UTF-8"); // set
char * result = setlocale (LC_ALL, NULL); // review
if(!strstr(result, "UTF-8"))
   printf("failed to set locale to UTF-8");
尝试:

您可以在终端中运行
locale-a
,以获得您的系统支持的区域设置的完整列表(“en_US.UTF-8”应得到大多数/所有UTF-8支持系统的支持)

编辑1(交替拼写)

Lee在评论中指出,有些系统有另一种拼写,
“en_US.utf8”
(这让我很惊讶,但我们每天都在学习新的东西)

由于
setlocale
失败时返回NULL,因此可以链接这些调用:

if(!setlocale(LC_ALL, "en_US.UTF-8") && !setlocale(LC_ALL, "en_US.utf8"))
   printf("failed to set locale to UTF-8");
编辑2(了解我们是否使用UTF-8)

要确定区域设置是否设置为UFT-8(在尝试设置之后),可以检查返回值(
NULL
表示调用失败)或检查使用的区域设置

备选案文1:

char * result;
if((result = setlocale (LC_ALL, "en_US.UTF-8")) == NULL)
   printf("failed to set locale to UTF-8");
备选案文2:

setlocale (LC_ALL, "en_US.UTF-8"); // set
char * result = setlocale (LC_ALL, NULL); // review
if(!strstr(result, "UTF-8"))
   printf("failed to set locale to UTF-8");

这是可能的,但这是完全错误的

首先,当前区域设置由用户决定。不仅仅是字符集,还有语言、日期和时间格式等等。你的程序绝对没有“权利”去搞乱它

如果您无法本地化您的程序,只需告诉用户您的程序的环境要求,并让他们担心它

实际上,您不应该真正依赖于UTF-8作为当前编码,而是使用广泛的字符支持,包括诸如、等函数。POSIXy系统还在其C库中提供和函数族,以在编码之间进行转换(应始终包括与
wchar\t
之间的转换);在Windows上,您需要一个单独的版本
libiconv
库。例如,GCC编译器就是这样处理不同的字符集的。(在内部,它使用Unicode/UTF-8,但如果您要求,它可以进行必要的转换以处理其他字符集。)

我个人强烈支持,但在程序中覆盖用户区域设置是可怕的。可恶的讨厌的就像一个桌面小程序改变显示分辨率,因为程序员特别喜欢某个分辨率

我很乐意编写一些示例代码来说明如何正确地解决任何字符集的合理情况,但是有太多了,我不知道从哪里开始

如果OP修改了他们的问题,准确地说明覆盖字符集应该解决什么问题,我愿意展示如何使用上述实用程序和POSIX工具(或Windows上免费提供的等效库)正确解决这个问题

如果这对某人来说似乎很苛刻,那是因为在这里采取简单易行的方法(覆盖用户的区域设置)是如此。。。完全是技术上的错误。即使没有更好的操作,实际上也是可以接受的,只要您只记录您的应用程序只处理UTF-8输入/输出


例1。新年快乐

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

int main(void)
{
    /* We wish to use the user's current locale. */
    setlocale(LC_ALL, "");

    /* We intend to use wide functions on standard output. */
    fwide(stdout, 1);

    /* For Windows compatibility, print out a Byte Order Mark.
     * If you save the output to a file, this helps tell Windows
     * applications that the file is Unicode.
     * Other systems don't need it nor use it.
    */
    fputwc(L'\uFEFF', stdout);

    wprintf(L"Happy New Year!\n");
    wprintf(L"С новым годом!\n");
    wprintf(L"新年好!\n");
    wprintf(L"賀正!\n");
    wprintf(L"¡Feliz año nuevo!\n");
    wprintf(L"Hyvää uutta vuotta!\n");

    return EXIT_SUCCESS;
}

上面的
getwline()
函数是处理本地化的宽字符支持时可能需要的最复杂的函数。它允许您在不受长度限制的情况下读取本地化的输入行,并可以选择修剪和清除(删除控制代码和嵌入的二进制零)返回的字符串。它也适用于LF和CR-LF(
\n
\r\n
)换行编码

这是可能的,但这是完全错误的

首先,当前区域设置由用户决定。不仅仅是字符集,还有语言、日期和时间格式等等。你的程序绝对没有“权利”去搞乱它

如果您无法本地化您的程序,只需告诉用户您的程序的环境要求,并让他们担心它

实际上,您不应该真正依赖于UTF-8作为当前编码,而是使用广泛的字符支持,包括诸如、等函数。POSIXy系统还在其C库中提供和函数族,以在编码之间进行转换(应始终包括与
wchar\t
之间的转换);在Windows上,您需要一个单独的版本
libiconv
库。例如,GCC编译器就是这样处理不同的字符集的。(在内部,它使用Unicode/UTF-8,但如果您要求,它可以进行必要的转换以处理其他字符集。)

我个人强烈支持,但在程序中覆盖用户区域设置是可怕的。可恶的讨厌的就像一个桌面小程序改变显示分辨率,因为程序员特别喜欢某个分辨率

我很乐意编写一些示例代码来演示如何正确地解决任何字符集sensib
 free(field);
 field = NULL;
 allocated = 0;