C语言如何正确与stdout通信以输出符合终端预期的可显示字符
如何判断终端期望接收的数据格式?该使用fputc、fputwc还是其他函数?
以下是我使用fputc做的测试:
// characters.c #include <ctype.h> #include <stdio.h> int main ( void ) { for ( int c = 0 ; c <= 65535 ; c ++ ) if ( isgraph ( c ) ) fputc ( c , stdout ) ; }
以下是我使用fputwc做的测试:
// wcharacters.c #include <ctype.h> #include <stdio.h> #include <wcahr.h> int main ( void ) { for ( wchar_t c = 0 ; c <= 65535 ; c ++ ) if ( isgraph ( c ) ) fputwc ( c , stdout ) ; }
运行characters.c时,终端输出的前几个字符符合ASCII规范(如!"#等),但输出到~之后就全是乱码。
运行wcharacters.c得到的结果类似,只是乱码替换为?或其他ASCII字符,其中绝大多数输出都是?。
我确认该终端支持Unicode码点十进制33到65535范围内的大量字符,因为我可以通过Python 3正常输出这些字符。
我当前的运行环境是Trisquel GNU/Linux、gcc(编译参数-std=c99),终端为MATE Terminal,字体为“Monospace”,这款字体虽然名字通用,但确实支持ASCII范围外的大量字符。
我可以接受使用更新版本的C标准,但我正在开发的项目核心要求之一是简洁性,而C标准每迭代一代都会变得更复杂,请问使用C17的uchar.h会不会更简单?
我开发的函数需要实现:用户将任意图形字符(即isgraph判定为真的字符)写入stdout时,这些字符都可以被“正确”显示。
补充内容
回复@chux-reinstate-monica的评论:
isgraph()适用于窄字符,不适用于宽字符。
我调整了一份比characters.c更合理的测试代码:
// charactersAll.c #include <ctype.h> #include <limits.h> #include <stdio.h> int main ( void ) { const int cmax = ( (unsigned) UCHAR_MAX < (unsigned) INT_MAX ) ? (int) UCHAR_MAX : INT_MAX ; int c = -1 ; while ( c < cmax ) { c ++ ; if ( isgraph ( c ) ) fputc ( c , stdout ) ; } }
和characters.c相比的优化点:
- 遍历了所有
isgraph的合法入参范围。 - 避免溢出:原
characters.c存在c自增超出int最大值的风险(比如int为16位的场景,该问题由@chux-reinstate-monica在补充说明中指出)。
内容的提问来源于stack exchange,提问作者Ana Nimbus
相关产品推荐
相关产品推荐

