关于cout,wcout输出的测试,以及printf,wprintf 输出中文,内存中直接输出图像给网页问题

一:cout,wcout输出测试

调试环境:VS2005 UNICODE

代码段如下

 

_setmode(fileno(stdout),_O_BINARY); TCHAR *pBuf = NULL; SafeArrayAccessData(varBLOB.parray,(void **)&pBuf); SafeArrayUnaccessData (varBLOB.parray); wcout<<pBuf<<endl; //输出应该为pBuf指向的从数据库读出的图像部分二进制数据(正确函数用法下面在介绍) cout<<&pBuf<<endl; //2 pBuf指针的地址 cout<<static_cast<void *>(pBuf)<<endl; //3 pBuf指向的二进制数据块首地址(如果想输出一个指针所指的地址,只要把此指针强制转换成 void * 即可,C++ Primer 3 中,cout一章有此例子) cout<<endl; TCHAR *test = L"adf"; cout<<test<<endl; //4 test指向的字符串常量首地址,至于为啥不是adf,原因在于test是宽字节,而cout是单字节输出函数,所以变成输出test的字符串第一个字节首地址 wcout<<test<<endl; // 此处输出为正确的adf,控制台中显示似乎还有一个空格。。 cout<<endl; char *testb = "abc"; cout<<testb<<endl; // 输出正确,且没空格 wcout<<testb<<endl; // 此处输出虽然也为字符,(与上一个例子不相反 - -!)但是字符中间有空格。。 //字符中间有空格的原因查明,是代码前有一段 _setmode(fileno(stdout),_O_BINARY);设置成二进制就会有空格。改成 _setmode(fileno(stdout),_O_TEXT);无空格

 

 

显示结果如下: 

 

关于cout,wcout输出的测试,以及printf,wprintf 输出中文,内存中直接输出图像给网页问题_第1张图片

 

另:

TCHAR *test = L"adf"; cout<<test<<endl; //输出为宽字符"a"低字节地址0049504C wcout<<test<<endl; //输出结果为"adf"; test++; cout<<test<<endl; //输出为宽字符"a"高字节地址0049504E wcout<<test<<endl; //输出结果为"df" cout<<test[0]<<endl; // 输出结果为100,应该为a的低字节值 wcout<<test[0]<<endl; //输出结果为a cout<<test[1]<<endl; //输出结果为102,应该为a的高字节值 wcout<<test[1]<<endl; //输出结果为d cout<<L"adsafb"<<endl; //输出结果为字符串首地址

 

 

二,从数据库中读出的图像二进制数据直接输出给浏览器

_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")->ActualSize; ///得到数据的长度 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/jpeg;/n/n"); _setmode(_fileno(stdout),_O_BINARY); cout.write((char*)pBuf,lDataSize ); //用此函数可以正确输出图像。 方法一 //wcout<<pBuf<<endl; //此函数只输出一部分就结束了,(见第一张图中的第一行),可能还需要其他步骤 PS:个人猜想,图像数据中有wcout 所认为的结束符。。 //以下几种方法,经测试均可以正常输出图像 //方法二: //long n = 0 ; //while(n < lDataSize) //lDataSize 的值为图像块数据的长度 //{ //cout<<((char*)pBuf)[n]; //正确 //n++; //} //方法三 //long n = 0 ; //while(n < lDataSize/2 ) //{ //wcout<<pBuf[n]; //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; pBuf = (TCHAR*)(_bstr_t)(varBLOB); fflush(stdout); _setmode(_fileno(stdout),_O_TEXT); fprintf(stdout,"Content-Type:image/jpeg;/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<<endl;

  wofs<<L"Another test还是测试"<<1234<<endl;

  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);

你可能感兴趣的:(c,UI,数据库,测试,语言,iostream)