在Linux中,C代码在哪里将内存中的字节编码为特定的字符集



在Linux的文档中:

LC_CTYPE

这一类别决定了字节序列作为字符的解释(例如,单字节字符与多字节字符)、字符分类(例如,字母或数字)以及字符类的行为。在glibc系统上,这个类别还确定了iconv(1)和iconv(3)的字符音译规则。它改变了字符处理和分类函数(如isupper(3)和toupper(3))以及多字节字符函数(如mblen(3)或wctomph(3)的行为。

然而,我看到了GCC的putwchar:源代码

/* _IO_putwc_unlocked */
# define _IO_putwc_unlocked(_wch, _fp)                                        
(__glibc_unlikely ((_fp)->_wide_data == NULL                                
|| ((_fp)->_wide_data->_IO_write_ptr                
>= (_fp)->_wide_data->_IO_write_end))                
? __woverflow (_fp, _wch)                                                
: (wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch)))
/* putwchar */
wint_t
putwchar (wchar_t wc)
{
wint_t result;
_IO_acquire_lock (stdout);
result = _IO_putwc_unlocked (wc, stdout);
_IO_release_lock (stdout);
return result;
}

没有代码使用setlocale()设置的区域设置,这让我很困惑。存储在内存中的字节何时何地传输到setlocale()设置的特定字符集?

更新:

int main() {
wchar_t wc = L'x00010437';
putwchar(wc); // print nothing
}
int main() {
wchar_t wc = L'x00010437';
setlocale(LC_CTYPE, "");
putwchar(wc); // print '  '
}

在上述两种情况下,setlocale()会影响屏幕上显示的字符。我想知道在哪个过程中,字节被确定为表示像"这样的特定字符?

更新2:

也许我找到了将多字节数据转换为特定字符集的源代码。以下是glibc/libio/wfileops.c:中_IO_wdo_write()中的代码片段

/* Now convert from the internal format into the external buffer.  */
result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
data, data + to_do, &new_data,
write_ptr,
buf_end,
&write_ptr);

扩展我的评论:

在Linux中,C代码在哪里将内存中的字节编码为特定的字符集?

据我所知,没有。字符集,又称字符编码,是从字符序列到字节序列的映射——从这个术语的抽象意义上来说。如果您查看的是内存中表示字符数据的字节,那么,您一定是在查看一个已经编码的表示。对于C程序,它们通常会根据C实现的执行字符集进行编码。

特别地;字符";以及";宽字符";类型实际上表示字符,它们包含编码的字符数据。在读取或写入此类数据时,通常不需要或执行转换,这就是为什么在glibc源代码中看不到它的原因。

当然,程序可以用其他编码方式对字符进行编码,并将生成的字节存储在内存中,例如通过iconv(3)。然后,程序有责任确保它们得到适当的处理。至于将编码的字节序列映射到视觉表示——";字形"——这是由显示或打印它们的程序执行的功能。一种方法是简单地选择具有从字节序列到字形的适当映射的字体。

最新更新