使用gSOAP开发实例(3) iconv解决中文乱码问题 .
2013-09-17 11:27
796 查看
http://blog.csdn.net/yui/article/details/5753879
电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。
我开发SOAP应用程序已经有一定的经验,在C/C++环境下一般使用gSOAP,而在Java环境下一般采用axis2。比较两者的话,除了开发语言之外,还是有不少差别,处理中文字符就是其中之一。网上分别搜索一下“axis2 乱码”和“gSOAP 乱码”,匹配的结果是相差很远的。Axis2好像比较智能,能够识别服务端的字符编码,这方面的问题也少,而最新版本的gSOAP,很可能还是需要程序员做多很多功夫。
在第一节客户端的教程中,输出的中文股票名称,其实就是乱码,不过为了主次之分,当时做了特别处理,忽略过去。
网上解决gSOAP乱码的主流方案是,初始化soap对象之后对其设置SOAP_C_UTFSTRING参数,例如:
struct soap soap;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
但是,单纯这样修改,在某些特定设置的机器上可能有效,反正我试过,仍然是乱码,如下图。怎么办呢?
Linux下有一个字符编码转换的工具iconv,同时也提供了一套可编程的接口。利用它,就可以测试出来自于服务端中文字符编码的类型,从而进一步实现在程序中自动转换编码。
Iconv常用用法是:iconv -t=to_charset -f=from_charset filename
因此,把需要转换编码的内容保存为一个文件,然后执行iconv试出需要转换的编码类型。from_charset几乎百分百肯定就是utf8,那么to_charset来来去去就那么几个,一个个试也很快试出来了。最终得出的结果是gbk编码,从而修改客户端程序以解决乱码问题。
[cpp]
view plaincopyprint?
#include <iconv.h>
#include "soapH.h"
#include "ChinaStockWebServiceSoap12.nsmap"
#define OUTPUT_LEN 32
int conv_charset(const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen) {
iconv_t conv = iconv_open(dest, src);
if ( conv == (iconv_t) -1 )
return -1;
memset(output, 0, olen);
if ( iconv(conv, &input, &ilen, &output, &olen) )
return -1;
iconv_close(conv);
return 0;
}
int main(int argc, char **argv) {
if ( argc != 2 && argc != 3 ) {
printf("Usage: %s stock_code [end_point]/n", argv[0]);
exit(-1);
}
struct soap soap;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
struct _ns1__getStockInfoByCode request;
struct _ns1__getStockInfoByCodeResponse response;
request.theStockCode = argv[1];
char *endpoint = NULL;
if ( argc == 3 )
endpoint = argv[2];
if ( soap_call___ns3__getStockInfoByCode(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) {
int element_counter = response.getStockInfoByCodeResult->__sizestring;
int i = 0;
for ( i = 0; i < element_counter; i++ ) {
switch ( i ) {
case 0 : printf("Stock code : "); break;
case 1 : printf("Stock name : "); break;
case 2 : printf("Timestamp : "); break;
case 3 : printf("Latest price : "); break;
case 4 : printf("Closing price T-1 : "); break;
case 5 : printf("Opening price : "); break;
case 6 : printf("Ups and downs : "); break;
case 7 : printf("Mininum price : "); break;
case 8 : printf("Maxinum price : "); break;
case 9 : printf("Amount of up/down : "); break;
case 10 : printf("Trading volume : "); break;
case 11 : printf("Trading amount : "); break;
case 12 : printf("Buy price : "); break;
case 13 : printf("Sell price : "); break;
case 14 : printf("Agency trans : "); break;
case 15 : printf("Buy 1 : "); break;
case 16 : printf("Buy 2 : "); break;
case 17 : printf("Buy 3 : "); break;
case 18 : printf("Buy 4 : "); break;
case 19 : printf("Buy 5 : "); break;
case 20 : printf("Sell 1 : "); break;
case 21 : printf("Sell 2 : "); break;
case 22 : printf("Sell 3 : "); break;
case 23 : printf("Sell 4 : "); break;
case 24 : printf("Sell 5 : "); break;
default : break;
}
//printf("%s/n", response.getStockInfoByCodeResult->string[i]);
size_t ilen = strlen(response.getStockInfoByCodeResult->string[i]);
char output[OUTPUT_LEN];
if ( conv_charset("GBK", "UTF-8", response.getStockInfoByCodeResult->string[i], ilen, output, OUTPUT_LEN) )
printf("%s/n", response.getStockInfoByCodeResult->string[i]);
else
printf("%s/n", output);
}
}
else {
soap_print_fault(&soap, stderr);
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
#include <iconv.h>#include "soapH.h"#include "ChinaStockWebServiceSoap12.nsmap"#define OUTPUT_LEN 32int conv_charset(const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen) { iconv_t conv = iconv_open(dest, src); if ( conv == (iconv_t) -1 ) return -1; memset(output, 0, olen); if ( iconv(conv, &input, &ilen, &output, &olen) ) return -1; iconv_close(conv); return 0;}int main(int argc, char **argv) { if ( argc != 2 && argc != 3 ) { printf("Usage: %s stock_code [end_point]/n", argv[0]); exit(-1); } struct soap soap; soap_init(&soap); soap_set_mode(&soap, SOAP_C_UTFSTRING); struct _ns1__getStockInfoByCode request; struct _ns1__getStockInfoByCodeResponse response; request.theStockCode = argv[1]; char *endpoint = NULL; if ( argc == 3 ) endpoint = argv[2]; if ( soap_call___ns3__getStockInfoByCode(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) { int element_counter = response.getStockInfoByCodeResult->__sizestring; int i = 0; for ( i = 0; i < element_counter; i++ ) { switch ( i ) { case 0 : printf("Stock code : "); break; case 1 : printf("Stock name : "); break; case 2 : printf("Timestamp : "); break; case 3 : printf("Latest price : "); break; case 4 : printf("Closing price T-1 : "); break; case 5 : printf("Opening price : "); break; case 6 : printf("Ups and downs : "); break; case 7 : printf("Mininum price : "); break; case 8 : printf("Maxinum price : "); break; case 9 : printf("Amount of up/down : "); break; case 10 : printf("Trading volume : "); break; case 11 : printf("Trading amount : "); break; case 12 : printf("Buy price : "); break; case 13 : printf("Sell price : "); break; case 14 : printf("Agency trans : "); break; case 15 : printf("Buy 1 : "); break; case 16 : printf("Buy 2 : "); break; case 17 : printf("Buy 3 : "); break; case 18 : printf("Buy 4 : "); break; case 19 : printf("Buy 5 : "); break; case 20 : printf("Sell 1 : "); break; case 21 : printf("Sell 2 : "); break; case 22 : printf("Sell 3 : "); break; case 23 : printf("Sell 4 : "); break; case 24 : printf("Sell 5 : "); break; default : break; } //printf("%s/n", response.getStockInfoByCodeResult->string[i]); size_t ilen = strlen(response.getStockInfoByCodeResult->string[i]); char output[OUTPUT_LEN]; if ( conv_charset("GBK", "UTF-8", response.getStockInfoByCodeResult->string[i], ilen, output, OUTPUT_LEN) ) printf("%s/n", response.getStockInfoByCodeResult->string[i]); else printf("%s/n", output); } } else { soap_print_fault(&soap, stderr); } soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0;}
测试成功,如下图:
电信provisioning系统中,常常需要与远程服务器实时交换一些数据,以完成用户的请求。由于简单对象访问协议(Simple Object Access Protocol, SOAP)的流行,许多涉及到第三方的应用,我们一般都比较乐意使用SOAP来开发。不过,由于可能涉及到公司的机密,本系列教程的开发实例尽量采用在网上已经公开的Web Service资源。
我开发SOAP应用程序已经有一定的经验,在C/C++环境下一般使用gSOAP,而在Java环境下一般采用axis2。比较两者的话,除了开发语言之外,还是有不少差别,处理中文字符就是其中之一。网上分别搜索一下“axis2 乱码”和“gSOAP 乱码”,匹配的结果是相差很远的。Axis2好像比较智能,能够识别服务端的字符编码,这方面的问题也少,而最新版本的gSOAP,很可能还是需要程序员做多很多功夫。
在第一节客户端的教程中,输出的中文股票名称,其实就是乱码,不过为了主次之分,当时做了特别处理,忽略过去。
网上解决gSOAP乱码的主流方案是,初始化soap对象之后对其设置SOAP_C_UTFSTRING参数,例如:
struct soap soap;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
但是,单纯这样修改,在某些特定设置的机器上可能有效,反正我试过,仍然是乱码,如下图。怎么办呢?
Linux下有一个字符编码转换的工具iconv,同时也提供了一套可编程的接口。利用它,就可以测试出来自于服务端中文字符编码的类型,从而进一步实现在程序中自动转换编码。
Iconv常用用法是:iconv -t=to_charset -f=from_charset filename
因此,把需要转换编码的内容保存为一个文件,然后执行iconv试出需要转换的编码类型。from_charset几乎百分百肯定就是utf8,那么to_charset来来去去就那么几个,一个个试也很快试出来了。最终得出的结果是gbk编码,从而修改客户端程序以解决乱码问题。
[cpp]
view plaincopyprint?
#include <iconv.h>
#include "soapH.h"
#include "ChinaStockWebServiceSoap12.nsmap"
#define OUTPUT_LEN 32
int conv_charset(const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen) {
iconv_t conv = iconv_open(dest, src);
if ( conv == (iconv_t) -1 )
return -1;
memset(output, 0, olen);
if ( iconv(conv, &input, &ilen, &output, &olen) )
return -1;
iconv_close(conv);
return 0;
}
int main(int argc, char **argv) {
if ( argc != 2 && argc != 3 ) {
printf("Usage: %s stock_code [end_point]/n", argv[0]);
exit(-1);
}
struct soap soap;
soap_init(&soap);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
struct _ns1__getStockInfoByCode request;
struct _ns1__getStockInfoByCodeResponse response;
request.theStockCode = argv[1];
char *endpoint = NULL;
if ( argc == 3 )
endpoint = argv[2];
if ( soap_call___ns3__getStockInfoByCode(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) {
int element_counter = response.getStockInfoByCodeResult->__sizestring;
int i = 0;
for ( i = 0; i < element_counter; i++ ) {
switch ( i ) {
case 0 : printf("Stock code : "); break;
case 1 : printf("Stock name : "); break;
case 2 : printf("Timestamp : "); break;
case 3 : printf("Latest price : "); break;
case 4 : printf("Closing price T-1 : "); break;
case 5 : printf("Opening price : "); break;
case 6 : printf("Ups and downs : "); break;
case 7 : printf("Mininum price : "); break;
case 8 : printf("Maxinum price : "); break;
case 9 : printf("Amount of up/down : "); break;
case 10 : printf("Trading volume : "); break;
case 11 : printf("Trading amount : "); break;
case 12 : printf("Buy price : "); break;
case 13 : printf("Sell price : "); break;
case 14 : printf("Agency trans : "); break;
case 15 : printf("Buy 1 : "); break;
case 16 : printf("Buy 2 : "); break;
case 17 : printf("Buy 3 : "); break;
case 18 : printf("Buy 4 : "); break;
case 19 : printf("Buy 5 : "); break;
case 20 : printf("Sell 1 : "); break;
case 21 : printf("Sell 2 : "); break;
case 22 : printf("Sell 3 : "); break;
case 23 : printf("Sell 4 : "); break;
case 24 : printf("Sell 5 : "); break;
default : break;
}
//printf("%s/n", response.getStockInfoByCodeResult->string[i]);
size_t ilen = strlen(response.getStockInfoByCodeResult->string[i]);
char output[OUTPUT_LEN];
if ( conv_charset("GBK", "UTF-8", response.getStockInfoByCodeResult->string[i], ilen, output, OUTPUT_LEN) )
printf("%s/n", response.getStockInfoByCodeResult->string[i]);
else
printf("%s/n", output);
}
}
else {
soap_print_fault(&soap, stderr);
}
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
#include <iconv.h>#include "soapH.h"#include "ChinaStockWebServiceSoap12.nsmap"#define OUTPUT_LEN 32int conv_charset(const char *dest, const char *src, char *input, size_t ilen, char *output, size_t olen) { iconv_t conv = iconv_open(dest, src); if ( conv == (iconv_t) -1 ) return -1; memset(output, 0, olen); if ( iconv(conv, &input, &ilen, &output, &olen) ) return -1; iconv_close(conv); return 0;}int main(int argc, char **argv) { if ( argc != 2 && argc != 3 ) { printf("Usage: %s stock_code [end_point]/n", argv[0]); exit(-1); } struct soap soap; soap_init(&soap); soap_set_mode(&soap, SOAP_C_UTFSTRING); struct _ns1__getStockInfoByCode request; struct _ns1__getStockInfoByCodeResponse response; request.theStockCode = argv[1]; char *endpoint = NULL; if ( argc == 3 ) endpoint = argv[2]; if ( soap_call___ns3__getStockInfoByCode(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) { int element_counter = response.getStockInfoByCodeResult->__sizestring; int i = 0; for ( i = 0; i < element_counter; i++ ) { switch ( i ) { case 0 : printf("Stock code : "); break; case 1 : printf("Stock name : "); break; case 2 : printf("Timestamp : "); break; case 3 : printf("Latest price : "); break; case 4 : printf("Closing price T-1 : "); break; case 5 : printf("Opening price : "); break; case 6 : printf("Ups and downs : "); break; case 7 : printf("Mininum price : "); break; case 8 : printf("Maxinum price : "); break; case 9 : printf("Amount of up/down : "); break; case 10 : printf("Trading volume : "); break; case 11 : printf("Trading amount : "); break; case 12 : printf("Buy price : "); break; case 13 : printf("Sell price : "); break; case 14 : printf("Agency trans : "); break; case 15 : printf("Buy 1 : "); break; case 16 : printf("Buy 2 : "); break; case 17 : printf("Buy 3 : "); break; case 18 : printf("Buy 4 : "); break; case 19 : printf("Buy 5 : "); break; case 20 : printf("Sell 1 : "); break; case 21 : printf("Sell 2 : "); break; case 22 : printf("Sell 3 : "); break; case 23 : printf("Sell 4 : "); break; case 24 : printf("Sell 5 : "); break; default : break; } //printf("%s/n", response.getStockInfoByCodeResult->string[i]); size_t ilen = strlen(response.getStockInfoByCodeResult->string[i]); char output[OUTPUT_LEN]; if ( conv_charset("GBK", "UTF-8", response.getStockInfoByCodeResult->string[i], ilen, output, OUTPUT_LEN) ) printf("%s/n", response.getStockInfoByCodeResult->string[i]); else printf("%s/n", output); } } else { soap_print_fault(&soap, stderr); } soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0;}
测试成功,如下图:
相关文章推荐
- 使用gSOAP开发实例(3) iconv解决中文乱码问题
- 使用gSOAP开发实例(4) iconv解决中文乱码问题(续) .
- 使用gSOAP开发实例(3) iconv解决中文乱码问题
- 使用gSOAP开发实例(4) iconv解决中文乱码问题(续)
- 使用gSOAP开发实例(3) iconv解决中文乱码问题
- 使用gSOAP开发实例(4) iconv解决中文乱码问题(续)
- 使用gSOAP开发实例(3) iconv解决中文乱码问题
- 使用gSOAP开发实例(4) iconv解决中文乱码问题(续)
- ASP.NET Core2.0 使用VSCode 版本1.13.1工具 开发控制台运行出现中文乱码问题及解决方法
- 支持Xcode6 IOS使用ZBar二维码扫描开发(解决arm64,arm7s兼容并解决中文乱码问题)
- Spring mvc 实例--使用velocity视图,解决中文乱码问题
- [Cocos2D-X]使用iconv解决VS上中文显示乱码的问题+android导入第三方库iconv
- javaweb开发中的中文乱码问题,使用Filter过滤器解决
- Ajax的底层实现--使用Ajax实现无刷新登录实例--解决ajax中URl参数带中文的乱码问题
- 解决openfire在使用MySQL数据库后的中文乱码问题
- Java socket保存示例(不使用base64)解决中文乱码问题
- 解决springmvc使用ResponseBody注解返回json中文乱码问题
- sublime text2 使用技巧-安装插件-中文乱码问题解决
- 使用JSP开发应用程序时的编码(中文等乱码)问题的建议解决方案(包括接受request和数据库操作)
- 解决使用secureCRT操作数据库时出现中文乱码问题