在 C 中打印 UTF-8 后未显示文本

Posted

技术标签:

【中文标题】在 C 中打印 UTF-8 后未显示文本【英文标题】:Text not showing after printing UTF-8 in C 【发布时间】:2021-12-07 13:16:03 【问题描述】:

我正在尝试在我的程序上打印一些 UTF-8 文本。当我执行正常打印功能时它不会显示,但在我使用#include<fcntl.h>#include <io.h>setmode(_fileno(stdout), _O_U16TEXT); 并将printf 转换为wprintf 后它确实有效。但是,在我使用了上面提到的那些行之后,它使我所有的正常打印行都不可见,只有 UTF-8 文本可见。我该如何解决这个问题?

这是我的代码:

#include<fcntl.h>
#include <io.h>
#include <stdio.h>

int main ()
setmode(_fileno(stdout), _O_U16TEXT); 

wprintf(L"░██████╗████████╗██╗░░░██╗██████╗░███████╗███╗░░██╗████████╗  ██╗░░░██╗░█████╗░████████╗██╗███╗░░██╗░██████╗░\n");printf("\n");
wprintf(L"██╔════╝╚══██╔══╝██║░░░██║██╔══██╗██╔════╝████╗░██║╚══██╔══╝  ██║░░░██║██╔══██╗╚══██╔══╝██║████╗░██║██╔════╝░\n");printf("\n");
wprintf(L"╚█████╗░░░░██║░░░██║░░░██║██║░░██║█████╗░░██╔██╗██║░░░██║░░░  ╚██╗░██╔╝██║░░██║░░░██║░░░██║██╔██╗██║██║░░██╗░\n");printf("\n");
wprintf(L"░╚═══██╗░░░██║░░░██║░░░██║██║░░██║██╔══╝░░██║╚████║░░░██║░░░  ░╚████╔╝░██║░░██║░░░██║░░░██║██║╚████║██║░░╚██╗\n");printf("\n");
wprintf(L"██████╔╝░░░██║░░░╚██████╔╝██████╔╝███████╗██║░╚███║░░░██║░░░  ░░╚██╔╝░░╚█████╔╝░░░██║░░░██║██║░╚███║╚██████╔╝\n");printf("\n");
wprintf(L"╚═╝░░░░╚═════╝░╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░  ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░╚══╝░╚═════╝░\n");printf("\n");
wprintf(L"░██████╗██╗░░░██╗░██████╗████████╗███████╗███╗░░░███╗\n");printf("\n");
wprintf(L"██╔════╝╚██╗░██╔╝██╔════╝╚══██╔══╝██╔════╝████╗░████║\n");printf("\n");
wprintf(L"╚█████╗░░╚████╔╝░╚█████╗░░░░██║░░░█████╗░░██╔████╔██║\n");printf("\n");
wprintf(L"░╚═══██╗░░╚██╔╝░░░╚═══██╗░░░██║░░░██╔══╝░░██║╚██╔╝██║\n");printf("\n");
wprintf(L"██████╔╝░░░██║░░░██████╔╝░░░██║░░░███████╗██║░╚═╝░██║\n");printf("\n");
wprintf(L"╚═════╝░░░░╚═╝░░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░░░░╚═╝\n");printf("\n"); 


printf("THIS BECOMES INVISIBLE");
printf("how do i make it visible???");

    return;

谢谢!

【问题讨论】:

【参考方案1】:

不能轻易将wprintf()printf() 混合:

每个流都有一个方向。在流与外部文件关联之后,但在对其执行任何操作之前,流是没有方向的。一旦一个宽字符输入/输出函数被应用到一个没有方向的流上,这个流就变成了一个宽方向的流。类似地,一旦将字节输入/输出函数应用于无方向的流,该流就变成了面向字节的流。只有调用freopen 函数或fwide 函数才能改变流的方向。 (成功调用 freopen 会删除任何方向。) C2x § 7.21.2 4

【讨论】:

能否在 UTF-8 文本显示后恢复正常,以便再次使用正常的printf()?或者,您能否向我推荐一个更好的方法来做到这一点?谢谢!【参考方案2】:

更改时保存原始模式,刷新并恢复模式以切换回来。您只能在 _O_U16TEXT 模式下使用宽标准输出函数。见docs中的两个注意事项:

Unicode 模式适用于宽打印功能(例如,wprintf)并且是 不支持窄打印功能。使用窄版印刷 Unicode 模式流上的函数触发断言。

和:

如果您将数据写入文件流,请使用以下命令显式刷新代码 fflush 在使用 _setmode 更改模式之前。如果不冲洗 代码,你可能会得到意想不到的行为。如果你还没有写 数据到流中,您不必刷新代码。

#include<fcntl.h>
#include <io.h>
#include <stdio.h>

int main () 
    auto old_mode = _setmode(_fileno(stdout), _O_U16TEXT);

    wprintf(L"░██████╗████████╗██╗░░░██╗██████╗░███████╗███╗░░██╗████████╗  ██╗░░░██╗░█████╗░████████╗██╗███╗░░██╗░██████╗░\n");
    wprintf(L"██╔════╝╚══██╔══╝██║░░░██║██╔══██╗██╔════╝████╗░██║╚══██╔══╝  ██║░░░██║██╔══██╗╚══██╔══╝██║████╗░██║██╔════╝░\n");
    wprintf(L"╚█████╗░░░░██║░░░██║░░░██║██║░░██║█████╗░░██╔██╗██║░░░██║░░░  ╚██╗░██╔╝██║░░██║░░░██║░░░██║██╔██╗██║██║░░██╗░\n");
    wprintf(L"░╚═══██╗░░░██║░░░██║░░░██║██║░░██║██╔══╝░░██║╚████║░░░██║░░░  ░╚████╔╝░██║░░██║░░░██║░░░██║██║╚████║██║░░╚██╗\n");
    wprintf(L"██████╔╝░░░██║░░░╚██████╔╝██████╔╝███████╗██║░╚███║░░░██║░░░  ░░╚██╔╝░░╚█████╔╝░░░██║░░░██║██║░╚███║╚██████╔╝\n");
    wprintf(L"╚═════╝░░░░╚═╝░░░░╚═════╝░╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░  ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░╚══╝░╚═════╝░\n");
    wprintf(L"░██████╗██╗░░░██╗░██████╗████████╗███████╗███╗░░░███╗\n");
    wprintf(L"██╔════╝╚██╗░██╔╝██╔════╝╚══██╔══╝██╔════╝████╗░████║\n");
    wprintf(L"╚█████╗░░╚████╔╝░╚█████╗░░░░██║░░░█████╗░░██╔████╔██║\n");
    wprintf(L"░╚═══██╗░░╚██╔╝░░░╚═══██╗░░░██║░░░██╔══╝░░██║╚██╔╝██║\n");
    wprintf(L"██████╔╝░░░██║░░░██████╔╝░░░██║░░░███████╗██║░╚═╝░██║\n");
    wprintf(L"╚═════╝░░░░╚═╝░░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░░░░╚═╝\n");

    fflush(stdout);
    _setmode(_fileno(stdout), old_mode);
    printf("This is no longer invisible\n");

输出:

░██████╗████████╗██╗░░░██╗██████╗░███████╗███╗░░██╗████████╗  ██╗░░░██╗░█████╗░████████╗██╗███╗░░██╗░██████╗░
██╔════╝╚══██╔══╝██║░░░██║██╔══██╗██╔════╝████╗░██║╚══██╔══╝  ██║░░░██║██╔══██╗╚══██╔══╝██║████╗░██║██╔════╝░
╚█████╗░░░░██║░░░██║░░░██║██║░░██║█████╗░░██╔██╗██║░░░██║░░░  ╚██╗░██╔╝██║░░██║░░░██║░░░██║██╔██╗██║██║░░██╗░
░╚═══██╗░░░██║░░░██║░░░██║██║░░██║██╔══╝░░██║╚████║░░░██║░░░  ░╚████╔╝░██║░░██║░░░██║░░░██║██║╚████║██║░░╚██╗
██████╔╝░░░██║░░░╚██████╔╝██████╔╝███████╗██║░╚███║░░░██║░░░  ░░╚██╔╝░░╚█████╔╝░░░██║░░░██║██║░╚███║╚██████╔╝
╚═════╝░░░░╚═╝░░░░╚═════╝░╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░  ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░╚══╝░╚═════╝░
░██████╗██╗░░░██╗░██████╗████████╗███████╗███╗░░░███╗
██╔════╝╚██╗░██╔╝██╔════╝╚══██╔══╝██╔════╝████╗░████║
╚█████╗░░╚████╔╝░╚█████╗░░░░██║░░░█████╗░░██╔████╔██║
░╚═══██╗░░╚██╔╝░░░╚═══██╗░░░██║░░░██╔══╝░░██║╚██╔╝██║
██████╔╝░░░██║░░░██████╔╝░░░██║░░░███████╗██║░╚═╝░██║
╚═════╝░░░░╚═╝░░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░░░░╚═╝
This is no longer invisible

【讨论】:

非常感谢先生!!!!!!!!!成功了!【参考方案3】:

我认为这是你的解决方案

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

int main(void)

    setlocale(LC_ALL, "");
    printf("░██████╗████████╗██╗░░░██╗██████╗░███████╗███╗░░██╗████████╗  ██╗░░░██╗░█████╗░████████╗██╗███╗░░██╗░██████╗░\n");
    printf("██╔════╝╚══██╔══╝██║░░░██║██╔══██╗██╔════╝████╗░██║╚══██╔══╝  ██║░░░██║██╔══██╗╚══██╔══╝██║████╗░██║██╔════╝░\n");
    printf("╚█████╗░░░░██║░░░██║░░░██║██║░░██║█████╗░░██╔██╗██║░░░██║░░░  ╚██╗░██╔╝██║░░██║░░░██║░░░██║██╔██╗██║██║░░██╗░\n");
    printf("░╚═══██╗░░░██║░░░██║░░░██║██║░░██║██╔══╝░░██║╚████║░░░██║░░░  ░╚████╔╝░██║░░██║░░░██║░░░██║██║╚████║██║░░╚██╗\n");
    printf("██████╔╝░░░██║░░░╚██████╔╝██████╔╝███████╗██║░╚███║░░░██║░░░  ░░╚██╔╝░░╚█████╔╝░░░██║░░░██║██║░╚███║╚██████╔╝\n");
    printf("╚═╝░░░░╚═════╝░╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░  ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░╚══╝░╚═════╝░\n");
    printf("░██████╗██╗░░░██╗░██████╗████████╗███████╗███╗░░░███╗\n");
    printf("██╔════╝╚██╗░██╔╝██╔════╝╚══██╔══╝██╔════╝████╗░████║\n");
    printf("╚█████╗░░╚████╔╝░╚█████╗░░░░██║░░░█████╗░░██╔████╔██║\n");
    printf("░╚═══██╗░░╚██╔╝░░░╚═══██╗░░░██║░░░██╔══╝░░██║╚██╔╝██║\n");
    printf("██████╔╝░░░██║░░░██████╔╝░░░██║░░░███████╗██║░╚═╝░██║\n");
    printf("╚═════╝░░░░╚═╝░░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░░░░╚═╝\n"); 
    
    printf("THIS BECOMES INVISIBLE\n");
    printf("how do i make it visible???\n");
    return 0;

输出:

░██████╗████████╗██╗░░░██╗██████╗░███████╗███╗░░██╗████████╗  ██╗░░░██╗░█████╗░████████╗██╗███╗░░██╗░██████╗░
██╔════╝╚══██╔══╝██║░░░██║██╔══██╗██╔════╝████╗░██║╚══██╔══╝  ██║░░░██║██╔��═██╗╚══██╔══╝██║████╗░██║██╔════╝░
╚█████╗░░░░██║░░░██║░░░██║██║░░██║█████╗░░██╔██╗██║░░░██║░░░  ╚██╗░██╔╝██║░░██║░░░██║░░░██║██╔██╗██║██║░░██╗░
░╚═══██╗░░░██║░░░██║░░░██║██║░░██║██╔══╝░░██║╚██��█║░░░██║░░░  ░╚████╔╝░██║░░██║░░�██║░░░██║██║╚████║██║░░╚██╗
██████╔╝░░░██║░░░╚██████╔╝██████╔╝███████╗██║░╚███║░░░██║░░░  ░░╚██╔╝��░╚█████╔╝░░░██║░░░██║██║░╚███║╚��█████╔╝
╚═╝░░░░╚═════╝░╚═════╝░�══════╝╚═╝░░╚══╝░░░╚═╝░░░  ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░╚══╝░╚═════╝░
░██████╗██╗░░░██╗░████��█╗████████╗███████╗███╗░░░███╗
�█╔════╝╚██╗░██╔╝██╔════╝╚══██╔═�╝██╔════╝████╗░████║
╚█████╗░░╚████╔╝░╚█████╗░░░░██║░░░█████╗░░██╔████╔██║
░╚═══██╗░░╚██╔╝░░░╚══��██╗░░░██║░░░██╔══╝░░██║╚██╔╝██║
██████╔╝░░░██║░░░██████╔╝░░░██║�░░███████╗██║░╚═╝░██║
╚═════╝░░░░╚═╝░░░╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░░░░╚═╝
THIS BECOMES INVISIBLE
how do i make it visible???

【讨论】:

不适用于 Windows。这就是为什么 OP 需要 non_standard _setmode

以上是关于在 C 中打印 UTF-8 后未显示文本的主要内容,如果未能解决你的问题,请参考以下文章

如何将新建文本文档的编码默认设为UTF-8格式?

怎样打印出文件夹下所有的文件名?

windows设置新建文本文档默认编码UTF-8

MIME php邮件仅显示文本/纯文本版本[关闭]

怎么把UTF-8编码的文本批量改成ANSI啊!!!!!!!!!?

通过添加跨度突出显示文本文档中的字符串