|
Posted on 2010-08-17 12:01 roy 閱讀(2903) 評論(5) 編輯 收藏 引用 所屬分類: C/C++
- 電信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編碼,從而修改客戶端程序以解決亂碼問題。
#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; }
- 測試成功,如下圖:
-

http://blog.csdn.net/yui/archive/2010/07/21/5753879.aspx
Feedback
# re: 使用gSOAP開發實例(3) iconv解決中文亂碼問題 回復 更多評論
2010-08-17 14:05 by
樓主試試這里提到的方法: http://www.cppprog.com/2009/0723/138_2.htmlsoap sp; soap_init(&sp); soap_set_mode(&sp, SOAP_C_UTFSTRING); sp.mode |= SOAP_C_UTFSTRING; //多加一句這個
# re: 使用gSOAP開發實例(3) iconv解決中文亂碼問題 回復 更多評論
2010-08-17 14:52 by
@毛毛
謝謝你,不過我寫本節之前已經試過了,不OK
# re: 使用gSOAP開發實例(3) iconv解決中文亂碼問題 回復 更多評論
2010-08-19 22:14 by
sp.mode |= SOAP_C_UTFSTRING; //多加一句這個
# re: 使用gSOAP開發實例(3) iconv解決中文亂碼問題 回復 更多評論
2010-08-19 23:32 by
@普派
It didn't work. Therefore, I had to find other ways.
# re: 使用gSOAP開發實例(3) iconv解決中文亂碼問題 回復 更多評論
2010-08-22 20:05 by
加了sp.mode |= SOAP_C_UTFSTRING;以后,就是以UTF8來傳送了,也就是說,發送時我們要轉碼成UTF8,收到的數據也是UTF8的,要轉回本地編碼或UNICODE編碼來輸出。
|