c++用cout与printff输出字符串遇到什么结束,比如说是不是读到空格就结束了? cout是不是一样呢

5335人阅读
编程之旅(17)
一:cout,wcout输出测试
调试环境:VS2005 UNICODE
代码段如下
_setmode(fileno(stdout),_O_BINARY);
TCHAR *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
SafeArrayUnaccessData (varBLOB.parray);
wcout&&pBuf&&
//输出应该为pBuf指向的从数据库读出的图像部分二进制数据(正确函数用法下面在介绍)
cout&&&pBuf&&
pBuf指针的地址
cout&&static_cast&void *&(pBuf)&&
pBuf指向的二进制数据块首地址(如果想输出一个指针所指的地址,只要把此指针强制转换成 void * 即可,C++ Primer 3 中,cout一章有此例子)
TCHAR *test = L"adf";
cout&&test&&
test指向的字符串常量首地址,至于为啥不是adf,原因在于test是宽字节,而cout是单字节输出函数,所以变成输出test的字符串第一个字节首地址
wcout&&test&&
此处输出为正确的adf,控制台中显示似乎还有一个空格。。
char *testb = "abc";
cout&&testb&&
// 输出正确,且没空格
wcout&&testb&&
// 此处输出虽然也为字符,(与上一个例子不相反 - -!)但是字符中间有空格。。
//字符中间有空格的原因查明,是代码前有一段 _setmode(fileno(stdout),_O_BINARY);设置成二进制就会有空格。改成 _setmode(fileno(stdout),_O_TEXT);无空格
显示结果如下:&
TCHAR *test = L"adf";
cout&&test&&
//输出为宽字符"a"低字节地址0049504C
wcout&&test&&
//输出结果为"adf";
cout&&test&&
//输出为宽字符"a"高字节地址0049504E
wcout&&test&&
//输出结果为"df"
cout&&test[0]&&
// 输出结果为100,应该为a的低字节值
wcout&&test[0]&& //输出结果为a
cout&&test[1]&&
//输出结果为102,应该为a的高字节值
wcout&&test[1]&&
//输出结果为d
cout&&L"adsafb"&& //输出结果为字符串首地址
二,从数据库中读出的图像二进制数据直接输出给浏览器
_variant_t varRecord(strRecord);
_variant_t varSQL(strSQL);
pRePtr-&Open(varSQL,varRecord,adOpenStatic,adLockReadOnly,adCmdText);
if(pRePtr-&GetRecordCount() == 0)
getnoneimage();
pRePtr-&Close();
pRePtr.Release();
pRePtr = NULL;
return TRUE;
//读出二进制数据
long lDataSize = pRePtr-&GetFields()-&GetItem("data")-&ActualS
///得到数据的长度
if(lDataSize & 0)
_variant_t varBLOB;
varBLOB = pRePtr-&GetFields()-&GetItem("data")-&GetChunk(lDataSize);
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
///判断数据类型是否正确,VT_UI1指无符号1字节整数(BYTE)数组
TCHAR *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
fflush(stdout);
_setmode(_fileno(stdout),_O_TEXT);
fprintf(stdout,"Content-Type:image//n/n");
_setmode(_fileno(stdout),_O_BINARY);
cout.write((char*)pBuf,lDataSize
//用此函数可以正确输出图像。 方法一
//wcout&&pBuf&&
//此函数只输出一部分就结束了,(见第一张图中的第一行),可能还需要其他步骤
PS:个人猜想,图像数据中有wcout 所认为的结束符。。
//以下几种方法,经测试均可以正常输出图像
//方法二:
//long n = 0 ;
//while(n & lDataSize)
//lDataSize 的值为图像块数据的长度
//cout&&((char*)pBuf)[n];
//long n = 0 ;
//while(n & lDataSize/2 )
//wcout&&pBuf[n];
//方法四:
//wcout.write(pBuf,lDataSize/2);
//cout.write(pBuf,lDataSize) //
出错,因为cout 输出的是char*型
SafeArrayUnaccessData (varBLOB.parray);
fflush(stdout);
_setmode(_fileno(stdout),_O_TEXT);
更简单的输出方法为:
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
///判断数据类型是否正确
TCHAR *pBuf = NULL;
= (TCHAR*)(_bstr_t)(varBLOB);
fflush(stdout);
_setmode(_fileno(stdout),_O_TEXT);
fprintf(stdout,"Content-Type:image//n/n");
_setmode(_fileno(stdout),_O_BINARY);
wcout.write(pBuf,lDataSize/2);
fflush(stdout);
_setmode(_fileno(stdout),_O_TEXT);
三,cout,wcout,printf,wprintf等函数的中文输出问题
需要说明的是,我的开发环境是VS 2005(标准库当然也是微软实现的),不保证其它环境下是相同的效果。
  1、cout和wcout
  在缺省的C locale下,cout可以直接输出中文,但对于wcout却不行(至少VS 2005下不行)。对于wcout,需要将其locale设为本地语言才能输出中文:
  wcout.imbue(locale(locale(),"",LC_CTYPE));& // ①
  也有人用如下语句的,但这会改变wcout的所有locale设置,比如数字&1234&会输出为&1,234&。
  wcout.imbue(locale(""));
  2、ofstream和wofstream
  在缺省的C locale下,ofstream能正确输出中文到文件中,但不支持中文文件名;wofstream支持中文文件名,但不能向文件中输出中文。要解决这个问题,需要在打开文件之前将全局locale设为本地语言。将全局locale设为本地语言后,ofstream和wofstream的问题都解决了,但 cout和wcout却不能输出中文了。要让cout和wcout输出中文,需要将全局locale恢复原来的设置,如下所示:
  locale &loc=locale::global(locale(locale(),"",LC_CTYPE));& // ②
  ofstream ofs("ofs测试.txt");
  wofstream wofs(L"wofs测试.txt");
  locale::global(loc);& // ③
  ofs&&"test测试"&&1234&&
  wofs&&L"Another test还是测试"&&1234&&
  3、printf和wprintf
  加上这两位C语言中的老兄,问题更加复杂。考虑如下语句(注意s的大小写):
  printf("%s", "multibyte中文/n");& // ④
  printf("%S", L"unicode中文/n");& // ⑤
  wprintf(L"%S", "multibyte中文/n");& // ⑥
  wprintf(L"%s", L"unicode中文/n");& // ⑦
  缺省情况下,⑤、⑦两条语句不能输出中文,这两条语句中字符串的形式是unicode形式的。如果在所有输出语句之前加上如下语句将C语言的全局locale设置为本地语言(C语言中只有全局locale)就可以正常输出了:
  setlocale(LC_CTYPE, "");& // ⑧
  但这会导致cout和wcout不能输出中文(汗,的确麻烦),将C语言的全局locale恢复后cout和wcout就正常了,如下所示:
  setlocale(LC_CTYPE, "C");& // ⑨
  但恢复后,printf和wprintf输出Unicode文本又不正常了(输出MultiByte文本总是正常的)。总不能每写一个 printf/wprintf就设置一次然后再恢复一次吧?所以,建议不要混用iostream和printf/wprintf,实在要混用,那就让 printf/wprintf只输出MultiByte字符串,这样不需要调用setlocale(),也就不会影响到cout和wcout.
  总之,用iostream、printf/wprintf输出中文,有点麻烦。概括起来要点如下:
  &如果要用wcout,需要在使用之前按语句①将其locale设置为本地语言;
  &如果要用ofstream或wofstream,要在打开文件之前按语句②将全局locale设为本地语言并保存初始的全局locale.然后在打开文件之后,按语句③将全局locale恢复为初始值;
  &不要混用iostream和printf/wprintf.如果要混用,只用printf/wprintf输出MultiByte字符串;
  &单独使用printf/wprintf时,如果要输出Unicode字符串,需要按语句⑧设置C语言的全局locale.如果只输出MultiByte字符串,则不需设置。
而我自己的代码中,用wprintf输出中文需要执行以下段代码即可,且wcout也可正常输出中文
TCHAR szACP[16];
wsprintf(szACP, _T(".%d"), GetACP());
_tsetlocale(LC_CTYPE, szACP);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:202331次
积分:2453
积分:2453
排名:第12044名
原创:34篇
转载:74篇
评论:34条
(2)(3)(4)(1)(3)(6)(3)(5)(6)(10)(43)(22)C++中cout输出字符型指针地址值的方法 - 单鱼游弋 - 博客园
posts - 151, comments - 56, trackbacks - 0, articles - 0
先给出通过字符型指针输出字符串的示例代码,如下:
#include &iostream&
using std::
using std::
int main()
const char *pszStr = "this is a string";
// 输出字符串
cout && "字符串:" && pszStr &&
// 显然不会输出地址值
cout && "字符串起始地址值: " && pszStr &&
对于要使用cout输出字符串指针地址值,我们可能会产生困惑。曾经我们使用C标准库中的printf函数是如此的方便:
#include &stdio.h&
int main()
const char *pszStr = "this is a string";
// 输出字符串
printf("字符串:%s\n", pszStr);
// 输出地址值
printf("字符串起始地址值:%p\n", pszStr);
兄弟,醒醒吧,咱们要写的是C++代码,不要总是抓着C不放嘛。好了,我们来分析一下,由于C++标准库中I/O类对&&操作符重载,因此在遇到字符型指针时会将其当作字符串名来处理,输出指针所指的字符串。既然这样,那么我们就别让它知道那是字符型指针,所以得用到强制类型转换,不过不是C的那套,我们得用static_cast来实现,把字符串指针转换成无类型指针,这样更规范,如下:
#include &iostream&
using std::
using std::
int main()
const char *pszStr = "this is a string";
// 输出字符串
cout && "字符串:" && pszStr &&
// 如我们所愿,输出地址值
cout && "字符串起始地址值: " && static_cast&const void *&(pszStr) &&

我要回帖

更多关于 printf cout 区别 的文章

 

随机推荐