首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

翻译程序记要和一点疑问

2013-06-25 
翻译程序记录和一点疑问我想把自己写的一个小程序翻到C++上.这个小程序是用来发布我们公司论坛上博彩的工

翻译程序记录和一点疑问
我想把自己写的一个小程序翻到C++上.
这个小程序是用来发布我们公司论坛上博彩的工具.
涉及到 wininet 如果你感兴趣可以看下去,

先说一下我的编程学习情况吧,我是从一个叫《易语言》转过来了,后来易语言已经满足不一些要求了,
它会报毒很影响使用心情,我就转到了C#上,可是公司的一个事情又让我转到了C++上,也就是最近才转过来的。
这里也不接受语言的优劣讨论,我只认为只要能很好的解决问题那都可以接受。
我的C#与C++的水平也就入门水平,所以文中可能会出现谬误。还请多给建议!
这只是我用来记录和给大家分享的文章,记录成份多一点吧。

好了,还是说说程序本身。

这个程序建议在post get的基本上的。
流程是这样的
先输入10个选手的名字,把它们加到博彩成员当中。
然后输入博彩的名字,有效时间(分钟)和成员(选手名/队色)完成发布

一开始我就直接建议了一个MFC项目,搞了半天才弄好界面,知道怎么得到属性,怎么设置属性.

到后面实现部分时,我遇到了第一个问题:分割的问题
因为有10个选手,一行一个选手名.所以要分割成数组存起来以后用.

因为在易与C#当中都有分割这一说,当然实现方式不一样。
易中是有查找这一命令与取得文本命令。
C#更简单,textbox中就有这么一个属性是一个多行文本数组。所以当时从易翻到C#上在这一步没有卡住。

找了一个发现了 find 与 mid  ,这两个方法完全能实现分割了.



CString playlist[10]={};
CString color[2]={_T("171"),_T("172")};
void C波菜实时发布系统CDlg::OnBnClickedButton1()
{
button_add.EnableWindow(false);
CString playname,name;

GetDlgItemText(IDC_EDIT1,playname);
playname+="\r\n";
int k=0,lastk=0,x=0;
while (k!=-1)
{
k=playname.Find(*"\r\n",lastk);
name=playname.Mid(lastk==0?lastk:lastk+1,k-(lastk==0?lastk:lastk+1));
if(name!=""){
playlist[x]=name;
x++;
}
lastk=k+1;
}
}

一开始我就发现了cstring 所以用了这个,但是后面发现这个真的让我一直很烦恼,好多的sting!
易中是用文本型来表示文本,最多也就转成字集节.当时文本的处理没让我感觉有多少烦恼.
C#中我也是先接触的string 他也能很出色的完成我所想的要求.

C++文本处理要多看一下.

实现了分割,下面就要post过去了.

我就想用wininet实现,因为我在易与 C#当时用的就是wininet 感觉它很快吧.

找了很多博客,看到了很好的文章,看着它,我写出了自己的wininet实现,
可是前面的的疑问更深了,
CString gethtml(CString url, CString postdata="")

首先 我前面所用的是CString 所以 再设定函数时我就把参数设成了CString 可是到里面很多的文本方式都变化了.

前面都还好操作到了 SendRequest这这块了.
HttpSendRequest(hRequest, 0, 0, const_cast<void*>(postdata), size)

因为前面postdata是CStringA声明的, 这个const_cast<void*> 我找了一下意思任何类型的指针,想一想也是post图片 post什么的,本质上也就是字节集吧

我找了一下 怎么把 cstring可以传过去.
找到了 cstringA 这个可以直接用 
(const char*)postdata

转成后就可以传过去了.
我就查找了一下 发现了这个设定:

引用
CStringA 对象包含基于 char 类型的字符串数据,并支持单字节和多字节(MBCS)字符串。 同样,CStringW 对象包含基于 wchar_t 类型的字符串数据,并且支持Unicode字符串。 CString 对象支持 char 类型或 wchar_t 类型。 哪个它支持取决于使用的符号,MBCS 或 UNICODE,在编译时定义。
---msdn


可能基础不是很好,还是有点迷,所以先放开它.

可是后面又出现了这样.

因为网站返回的是uft8编码的,我要解码,找到了一个
CStringW GetStringWFromUtf8(const std::string& str)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), 0, 0);

    CStringW buf;
    WCHAR*    dd = buf.GetBuffer(len);

    len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), dd, len);

    buf.ReleaseBuffer(len);

    return buf;
}

我一开始以为 cstring可以直接传过去,发现不可以.
但是char []可以传过去.
kp+=GetStringWFromUtf8(szBuf);

kp是这么声明的
CString kp;

至此,这个函数可算是工作了!
放上完整的源码,后来人可以参考
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string> 



#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#include <atlbase.h>
#include <atlstr.h>



#define USE_WINHTTP    //Comment this line to user wininet.
#ifdef USE_WINHTTP
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")
#else
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
#endif
#define BUF_SIZE    (1024)

// CrackedUrl
class CrackedUrl {
int m_scheme;
CStringW m_host;
int m_port;
CStringW m_path;
public:
CrackedUrl(LPCWSTR url)
{
URL_COMPONENTS uc = { 0};
uc.dwStructSize = sizeof(uc);

const DWORD BUF_LEN = 256;

WCHAR host[BUF_LEN];
uc.lpszHostName = host;
uc.dwHostNameLength = BUF_LEN;

WCHAR path[BUF_LEN];
uc.lpszUrlPath = path;
uc.dwUrlPathLength = BUF_LEN;

WCHAR extra[BUF_LEN];
uc.lpszExtraInfo = extra;
uc.dwExtraInfoLength = BUF_LEN;

#ifdef USE_WINHTTP
if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
printf("Error:WinHttpCrackUrl failed!/n");
}

#else
if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
printf("Error:InternetCrackUrl failed!/n");
}
#endif
m_scheme = uc.nScheme;
m_host = host;
m_port = uc.nPort;
m_path = path;
}

int GetScheme() const
{
return m_scheme;
}

LPCWSTR GetHostName() const
{
return m_host;
}

int GetPort() const
{
return m_port;
}

LPCWSTR GetPath() const
{
return m_path;
}

static CStringA UrlEncode(const char* p)
{
if (p == 0) {
return CStringA();
}

CStringA buf;

for (;;) {
int ch = (BYTE) (*(p++));
if (ch == '/0') {
break;
}

if (isalnum(ch) || ch == '_' || ch == '-' || ch == '.') {
buf += (char)ch;
}
else if (ch == ' ') {
buf += '+';
}
else {
char c[16];
wsprintfA(c, "%%%02X", ch);
buf += c;
}
}

return buf;
}
};

// CrackedUrl
HINTERNET OpenSession(LPCWSTR userAgent = 0)
{
#ifdef USE_WINHTTP
return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);;
#else
return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
#endif
}

HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)
{
#ifdef USE_WINHTTP
return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0);
#else
return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
#endif
}

HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb, LPCWSTR objectName, int scheme)
{
DWORD flags = 0;


#ifdef USE_WINHTTP
if (scheme == INTERNET_SCHEME_HTTPS) {
flags |= WINHTTP_FLAG_SECURE;
}

return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags);

#else
if (scheme == INTERNET_SCHEME_HTTPS) {
flags |= INTERNET_FLAG_SECURE;
}

return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0);
#endif
}

BOOL AddRequestHeaders(HINTERNET hRequest, LPCWSTR header)
{
SIZE_T len = lstrlenW(header);
#ifdef USE_WINHTTP
return WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
#else
return HttpAddRequestHeaders(hRequest, header, DWORD(len), HTTP_ADDREQ_FLAG_ADD);
#endif
}

BOOL SendRequest(HINTERNET hRequest, const void* body, DWORD size)
{
#ifdef USE_WINHTTP
return WinHttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size, size, 0);
#else
return HttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size);
#endif
}

BOOL EndRequest(HINTERNET hRequest)
{
#ifdef USE_WINHTTP
return WinHttpReceiveResponse(hRequest, 0);
#else
// if you use HttpSendRequestEx to send request then use HttpEndRequest in here!
return TRUE;
#endif
}

BOOL QueryInfo(HINTERNET hRequest, int queryId, char* szBuf, DWORD* pdwSize)
{
#ifdef USE_WINHTTP
return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0);
#else
return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0);
#endif
}

BOOL ReadData(HINTERNET hRequest, void* buffer, DWORD length, DWORD* cbRead)
{
#ifdef USE_WINHTTP
return WinHttpReadData(hRequest, buffer, length, cbRead);
#else
return InternetReadFile(hRequest, buffer, length, cbRead);
#endif
}
CStringW GetStringWFromUtf8(const std::string& str)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), 0, 0);

    CStringW buf;
    WCHAR*    dd = buf.GetBuffer(len);

    len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), int(str.length()), dd, len);

    buf.ReleaseBuffer(len);

    return buf;
}
void CloseInternetHandle(HINTERNET hInternet)
{
if (hInternet)
{
#ifdef USE_WINHTTP
WinHttpCloseHandle(hInternet);
#else
InternetCloseHandle(hInternet);
#endif
}
}

CString gethtml(CString url, CStringA postdata="")
{
USE_WINHTTP(0);
HINTERNET hSession = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
CStringW strHeader(L"Content-type: application/x-www-form-urlencoded/r/n");

// Test data
CrackedUrl crackedUrl(url);
//CStringA strPostData(postdata);

// Open session.
hSession = OpenSession(L"HttpPost by l_zhaohui@163.com");


if (hSession == NULL) {
printf("Error:Open session!/n");

}

// Connect.
hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort());
if (hConnect == NULL) {
printf("Error:Connect failed!/n");

}

// Open request.
hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme());
if (hRequest == NULL) {
printf("Error:OpenRequest failed!/n");

}

// Add request header.
if (!AddRequestHeaders(hRequest, strHeader)) {
printf("Error:AddRequestHeaders failed!/n");

}

// Send post data.
if (!SendRequest(hRequest, (const char*)postdata, postdata.GetLength())) {
printf("Error:SendRequest failed!/n");

}

// End request
if (!EndRequest(hRequest)) {
printf("Error:EndRequest failed!/n");

}

char szBuf[BUF_SIZE+1];
DWORD dwSize = 0;
szBuf[0] = 0;

// Query header info.
#ifdef USE_WINHTTP
int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH;
int statusCodeId = WINHTTP_QUERY_STATUS_CODE;
int statusTextId = WINHTTP_QUERY_STATUS_TEXT;
#else
int contextLengthId = HTTP_QUERY_CONTENT_LENGTH;
int statusCodeId = HTTP_QUERY_STATUS_CODE;
int statusTextId = HTTP_QUERY_STATUS_TEXT;
#endif
dwSize = BUF_SIZE;
if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize)) {
szBuf[dwSize] = 0;
printf("Content length:[%s]/n", szBuf);
}

dwSize = BUF_SIZE;
if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize)) {
szBuf[dwSize] = 0;
printf("Status code:[%s]/n", szBuf);
}

dwSize = BUF_SIZE;
if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize)) {
szBuf[dwSize] = 0;
printf("Status text:[%s]/n", szBuf);
}
CString kp;
// read data.
for (;;) {
dwSize = BUF_SIZE;
if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE) {
break;
}

if (dwSize <= 0) {
break;
}

szBuf[dwSize] = 0;
kp+=GetStringWFromUtf8(szBuf);

}

CloseInternetHandle(hRequest);
CloseInternetHandle(hConnect);
CloseInternetHandle(hSession);

return kp;
}


[解决办法]
LZ很有毅力。

热点排行