這是一個非常簡單的例子,作為新手的我是拿來練手的,當然也可以給和我一樣的朋友一些參考。
而且圖靈官網沒有給出C的例子,網上一搜也是各種Java、C#甚至易語言實現,不要歧視C++好不好●︿●,就算不如語言老大PHP,它也是很強的!
這個例子其本質就是一個C++寫的get數據 (POST和這個也差不多啦,可以自己動手試一試╭(′▽`)╯ )
沒有用MFC,直接用的WindowAPI哦,用的是winhttp。
也沒有使用JSON庫之類的來解析數據,因為我是暴力拆解字符串的,所以如果返回值位數不對可能會亂碼(大霧)。
好了,放源碼:
1 /* 2 圖靈機器人 C++實現 3 4 極簡版 5 幾乎沒有界面(廢話,畢竟是控制台) 6 7 代碼參考自微軟提供的例子,見: 8 https://msdn.microsoft.com/en-us/library/windows/desktop/aa384104(v=vs.85).aspx 9 */ 10 11 #include <iostream> 12 #include <Windows.h> 13 #include <winhttp.h> 14 #pragma comment(lib,"winhttp.lib") 15 16 #define TULING_URL L"www.tuling123.com/openapi/api?key=這里換成你自己從圖靈申請的API啦&info=%s" 17 static wchar_t String[1024]; 18 19 //編碼轉換 20 char *UnicodeToANSI(const wchar_t *str) 21 { 22 static char result[1024]; 23 int len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); 24 WideCharToMultiByte(CP_ACP, 0, str, -1, result, len, NULL, NULL); 25 result[len] = '\0'; 26 return result; 27 } 28 wchar_t *UTF8ToUnicode(const char *str) 29 { 30 static wchar_t result[1024]; 31 int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); 32 MultiByteToWideChar(CP_UTF8, 0, str, -1, result, len); 33 result[len] = L'\0'; 34 return result; 35 } 36 wchar_t *ANSIToUnicode(const char* str) 37 { 38 int textlen; 39 static wchar_t result[1024]; 40 textlen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 41 memset(result, 0, sizeof(char) * (textlen + 1)); 42 MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)result, textlen); 43 return result; 44 } 45 46 bool GetHttpPage(void) 47 { 48 DWORD dwSize = 0; 49 DWORD dwDownloaded = 0; 50 LPSTR pszOutBuffer = NULL; 51 static HINTERNET hSession = WinHttpOpen(L"A Tuling API Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 52 static HINTERNET hConnect = NULL, hRequest = NULL; 53 BOOL bResults = FALSE; 54 55 //從控制台讀出一行文字,注意讀出來的內容是ANSI編碼的,我們需要轉換成 Unicode編碼 56 static char uin[1024]; gets_s(uin); 57 wsprintf(String, TULING_URL, ANSIToUnicode(uin)); 58 59 //建立一個http的連接會話,給出主機名就行,可以域名,也可以是IP地址,不需要http;前綴 60 if (hSession) 61 { 62 if (!hConnect) 63 hConnect = WinHttpConnect(hSession, L"www.tuling123.com", INTERNET_DEFAULT_HTTP_PORT, 0); 64 } 65 66 //創建一個HTTP請求句柄 67 if (hConnect) 68 hRequest = WinHttpOpenRequest(hConnect, L"GET", String, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_PERCENT | WINHTTP_FLAG_REFRESH); 69 70 //發送請求數據 71 if (hRequest) 72 bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 73 74 // 請求結束,接收數據 75 if (bResults) 76 bResults = WinHttpReceiveResponse(hRequest, NULL); 77 else 78 printf("Error %d has occurred.\n", GetLastError()); 79 //如果返回值為false,可以使用getlasterror來得到錯誤信息,下同 80 //返回值的詳細信息可以看微軟網頁,或者看這里翻譯好的中文接口說明 81 //http://blog.csdn.net/fengsh998/article/details/8201591 82 83 // 內部使用的一個循環來確保能接受到所有數據 84 if (bResults) 85 { 86 do 87 { 88 //檢查是否還有數據需要接收 89 dwSize = 0; 90 if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) 91 { 92 printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); 93 break; 94 } 95 96 if (!dwSize) 97 break; 98 99 //為緩沖分配內存並讀取 100 pszOutBuffer = new char[dwSize + 1]; 101 102 if (!pszOutBuffer) 103 { 104 printf("Out of memory\n"); 105 break; 106 } 107 108 ZeroMemory(pszOutBuffer, dwSize + 1); 109 110 if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) 111 { 112 printf("Error %u in WinHttpReadData.\n", GetLastError()); 113 } 114 else 115 { 116 //圖靈api返回來的內容使用的是UTF-8編碼,我們需要把它轉換回ANSI才能在控制台顯示 117 //printf("return:%s\n", UnicodeToANSI(UTF8ToUnicode(pszOutBuffer)) ); 118 119 //因為沒有使用JSON庫,所以我暴力拆了這字符串。 120 pszOutBuffer[strlen(pszOutBuffer)-2] = '\0'; 121 printf("小靈:%s\n\n", UnicodeToANSI(UTF8ToUnicode(pszOutBuffer)) + 23); 122 return true; 123 } 124 125 delete[] pszOutBuffer; 126 if (!dwDownloaded) 127 break; 128 129 } while (dwSize > 0); 130 } 131 132 //收尾,關閉被打開的句柄 133 if (hRequest) WinHttpCloseHandle(hRequest); 134 if (hConnect) WinHttpCloseHandle(hConnect); 135 if (hSession) WinHttpCloseHandle(hSession); 136 137 return false; 138 } 139 140 int main(void) 141 { 142 system("color F0"); 143 system("title 會聊天的圖靈機器人 ●﹏●"); 144 printf("\n 我是小靈,快來和我聊天吧! ●▽●\n\n"); 145 146 do{ printf("我:"); } while (GetHttpPage()); 147 148 system("pause"); 149 return 0; 150 }
VS2013可以直接Paste后編譯就用,額需要注意的是使用 Unicode 字符集,如果不是的話可能會出現不可預料的東西(因為我沒試過╮(╯▽╰)╭)
所有代碼包括注釋加起來是150行,編譯后也才10K左右,可以放心食用!
哦,再放張圖片好了