C++ 什么';是printf(“%s”)、printf(“%ls”)、wprintf(“%s”)和wprintf(“%ls”)之间的区别吗?

C++ 什么';是printf(“%s”)、printf(“%ls”)、wprintf(“%s”)和wprintf(“%ls”)之间的区别吗?,c++,unicode,printf,widechar,C++,Unicode,Printf,Widechar,考虑以下示例程序: #include <cstdio> #include <cwchar> #include <string> int main() { std::string narrowstr = "narrow"; std::wstring widestr = L"wide"; printf("1 %s \n", narrowstr.c_str()); printf("2 %ls \n", widestr.c_str()

考虑以下示例程序:

#include <cstdio>
#include <cwchar>
#include <string>

int main()
{
    std::string narrowstr = "narrow";
    std::wstring widestr = L"wide";
    printf("1 %s \n", narrowstr.c_str());
    printf("2 %ls \n", widestr.c_str());
    wprintf(L"3 %s \n", narrowstr.c_str());
    wprintf(L"4 %ls \n", widestr.c_str());

   return 0;
}
我想知道:

  • 为什么3&4没有打印
  • 1和3以及2和4之间的区别是什么
  • 如果窄带str在utf8中,而宽带tr在utf16中,有什么区别吗

  • 问题1和2的答案在文档中。任何一套好的文档都可以。他们说这很好

    至于3,语言标准没有规定字符串的任何特定编码,也没有规定
    wchar\u t
    的任何特定大小。您需要查阅实现文档,而不是语言本身的文档(尽管很少建议编写依赖于实现的代码)。

    您需要执行以下操作:

    wprintf(L"3 %hs \n", narrowstr.c_str());
    wprintf(L"4 %s \n", widestr.c_str());
    
    为什么??因为对于
    printf
    %s表示窄字符字符串。对于
    wprintf
    %ls表示宽

    但是,对于
    wprintf
    %s表示宽,%ls表示宽本身%hs意味着狭窄(对两者而言)。对于
    printf
    %s,以这种方式表示%hs


    在VC++/Windows上,
    %S
    (大写字母S)会扭转这种效果。因此,
    printf(“%S”)
    表示宽,
    wprintf(“%S”)
    表示窄。这对于
    \u tprintf

    非常有用。请注意,您使用的是C流。C流有一种非常特殊的特性,称为“定向”。溪流要么是无方向的,要么是宽的,要么是窄的。方向由对任何特定流的第一次输出决定(有关C I/O流的摘要,请参阅)

    在您的例子中,
    stdout
    开始时没有方向,通过执行第一个
    printf
    ,您将其设置为窄值。一旦变窄,它就会被卡住,并且
    wprintf
    失败(检查其返回代码!)。更改C流的唯一方法是
    freopen
    it,这对stdout不太起作用。这就是为什么3和4没有打印出来

    1和3之间的区别在于1是一个使用窄字符串转换说明符%s的窄输出函数:它从字符数组读取字节,并将字节发送到字节流。3是一个具有窄字符串转换说明符%s的宽输出函数:它首先从字符数组中读取字节,然后将其读入
    wchar\t
    s,然后将
    wchar\t
    s发送到宽流中,然后,
    wc将它们转换成字节或多字节序列,然后通过
    write


    最后,如果widestr在utf16中,那么您必须使用Windows,并且所有赌注都已取消;在这个平台上,除了ASCII之外,几乎不支持任何东西。您也可以放弃并使用WinAPI(对于一些Unicode的事情,您可以使用标准C++11,甚至可以使用神奇的单词
    \u setmode(\u fileno(stdout),\u O\u U16TEXT);
    ,已经讨论了很多次了)

    等等!为什么它甚至不打印数字??您是否检查了wprintf是否工作?“WideTR在utf16中”表示您使用的是Windows(对Unicode更友好的系统使用UTF-32作为宽字符串的默认值)。如果你想在Windows系统上使用标准C++或C做任何事情,你可以跳过很多神秘的箍,你也可以放弃并使用WINAPII。不要屈服于微软的愚蠢。省去你的痛苦,编写你自己的字符串库。看在上帝的份上,不要使用windows宏转换和其他疯狂的操作,相信我,这太可怕了,在混乱中,各种各样的错误悄悄地出现了。#4可能没有打印出来,因为你的程序在#3上崩溃了
    %ls
    是打印
    wchar\u t
    字符串的最便捷的方式,可从
    printf
    wprintf
    两种方式工作。你应该避免使用<代码> %s>代码>,因为它的Visual C++解释与C99/C++ 11标准完全相反。
    wprintf(L"3 %hs \n", narrowstr.c_str());
    wprintf(L"4 %s \n", widestr.c_str());