sprintf和swprintf

来源:互联网 发布:淘宝电器销售额 编辑:程序博客网 时间:2024/06/10 04:55
setlocal对这两个函数的影响。
操作环境。ubuntu,local  zh_CN.utf8
测试printf,sprintf,

10 setlocale(LC_ALL, "zh_CN.utf8");
(gdb) n
22 sprintf(aa,"%ls",L"中国");
(gdb) n
23 printf("%ls",L"中国");
(gdb) x/10x aa
0x7fffffffdd80: 0xe5adb8e4 0x0000bd9b 0x00000000 0x00000000
0x7fffffffdd90: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffdda0: 0x00000000 0x00000000


如果setlocal不设置,
则aa,全部为0.而且打印为空

也就是说,sprintf和printf %ls的时候内部均做了一次编码转换,往local上靠拢。
这里就是unicode 转utf8.


测试swprintf
19 swprintf(aa,L"%s","中国");
(gdb)
20 swprintf(aa,L"is %ls",L"中国");
(gdb) x/10x aa
0x7fffffffdd80: 0xe5adb8e4 0x0000bd9b 0x00002500 0x00007300
0x7fffffffdd90: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffdda0: 0x00000000 0x00000000
(gdb) n
26 }
(gdb) x/10x aa
0x7fffffffdd80: 0x00004e2d 0x000056fd 0x00000000 0x00007300
0x7fffffffdd90: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffdda0: 0x00000000 0x00000000
对于swprintf来说,并没有往local靠拢的意思,也咩有往unicode靠拢的意愿,而且%s和%ls完全一样的结果。
给什么就收集什么,不做任何转换,只要不碰到unicode个0.



测试wprintf
setlocale(LC_ALL, "zh_CN.utf8");

 wprintf(L"%s","中国");
(gdb)
23 wprintf(L"%ls",L"中国");
(gdb)
25 wprintf(L"%s",L"中国");
(gdb)
27 wprintf(L"%ls","中国");
(gdb)
34 }
(gdb) c
Continuing.
中国中国-N?붛─猀[Inferior 1 (process 5430) exited normally]

setlocale(LC_ALL, "C");
21 wprintf(L"%s","中国");
(gdb) n
23 wprintf(L"%ls",L"中国");
(gdb) n
25 wprintf(L"%s",L"中国");
(gdb) n
27 wprintf(L"%ls","中国");
(gdb) n
34 }
(gdb) n
0x0000000000400ca6 in generic_start_main ()
(gdb) c
Continuing.
??-N??%s[Inferior 1 (process 5499) exited normally]

可以见到,setlocal对这个函数有作用的,可以理解为全部转化为unicode编码,再转化为本地输出。
为什么说%s,wprintf做了一次往unicode转化呢,如果没做,则应该%s输出是正确的才对.
wprintf(L"%s","中国");可以看到。当设置不同的local的时候,输出不一样。
而printf("%s","中国");则完全不受设置的local影响。



总结:
printf  ==
{
sprintf(buf)//%ls做local转换.也就是wcstombs.
puts(buf);
}


wprintf() ==
{
 
 [
mbstowcs() //%s往unicode转.  验证模型
  wcstombs();   //往本地local转换,
 ]

   [
wcstombs(); %ls往local转换.  错误模型.
   ]    
    puts();
}