比如,我抓取www.chinaz.com的首页,出现有内容有如下:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="baidu-site-verification" content="is0341Kwl2StOvGD" />
<title>站长之家 - 中国站长??- 站长资讯 | 我们致力于为中文网站提供动力??/title>
<meta name="keywords" content="站长,站长之家,站长资讯,创业??产品经理,网站运营,网络赚钱,电子商务,站长??站长工具,中国站长??>
<meta name="description" content="站长之家(中国站长??为个人站长与企业网络提供全面的站长资讯、最新最全的源代码程序下载、海量建站素材、强大的搜索优化辅助工具、网络产品设计与运营理念以及一站式网络解决方案,十年来我们一直致力为中文网站提供动力??>注意后面的问号
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="baidu-site-verification" content="is0341Kwl2StOvGD" />
<title>站长之家 - 中国站长??- 站长资讯 | 我们致力于为中文网站提供动力??/title>
<meta name="keywords" content="站长,站长之家,站长资讯,创业??产品经理,网站运营,网络赚钱,电子商务,站长??站长工具,中国站长??>
<meta name="description" content="站长之家(中国站长??为个人站长与企业网络提供全面的站长资讯、最新最全的源代码程序下载、海量建站素材、强大的搜索优化辅助工具、网络产品设计与运营理念以及一站式网络解决方案,十年来我们一直致力为中文网站提供动力??>注意后面的问号
解决方案 »
- 关于String的字符串提取问题!
- 【新手求助】怎样根据指定的图片文件大小,缩放jpg图片?
- 求一点资料,关于数据采集的
- 内存为什么显示是1023
- 如何避免多次启动同一个位置的同一程序?
- 用DC显示图片时,怎样滤掉一种颜色?就是不要底色,该怎么办呢?给100分
- 请问,MSDN里面列出来的虚拟键值只有那些功能键可以用啊。字母和数字不行啊。
- 用CreateWindow动态生成的按钮怎么知道它的ID
- 怎样用MFC打印预览listview结构的报表视图,需要重载那些函数?
- 修改WINDOWS窗口风格的问题,高手请进!
- 求大神帮助,如何设置对话框界面风格,感激不尽
- 关于在DLL中创建以主程序MainFram为父窗口的浮动窗口(浮空窗口是基类为CDockablePane的属性页窗口)
你 --〉0xe4, 0xbd, 0xa0
好 --> 0xe5, 0xbd, 0x21
1)如果入口参数为 char* / std::string (即用多字节表示汉字)时,汉字因为已经用2个字节(窄字符)表示,此时的UTF8编码已近不是对该汉字的码值编码,而是对组成该汉字的两个字符进行utf8编码,结果自然不对了。因此乱码。
UTF8(0xAABB) != UTF8(0XAA + 0XBB)
2)如果入口参数为 wchar_t* / std:wstring(即一个汉字用一个字符表示)时,汉字因为用1个宽字符表示(两个字节),因此UTF8转换没有问题。我用MFC调用WebService时使用到gSOAP,遇到中文乱码问题。解决方案参见我的博客
http://blog.csdn.net/xjkstar/article/details/20052443
转换后部分位置出现?是因为对应位置的UTF8字符,没有合适的Unicode字符对应
wchar_t* CzzbaoApp::Utf8ToUnicode(char *szU8)//utf8转unicode的参数改为宽字符串wchar_t*
CString CzzbaoApp::gethtml(CString listurl)
{
try
{
CInternetSession mySession(NULL,0); //开始抓取网页验证登陆
CHttpFile* myHttpFile=NULL; char strBuff[2049] = {0};
//string strHtml;
CString strHtml; myHttpFile=(CHttpFile*)mySession.OpenURL(listurl,1,INTERNET_FLAG_TRANSFER_ASCII|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD); int nReadLength=0;
while(nReadLength = myHttpFile->Read((void*)strBuff, 2048))
{
strBuff[nReadLength]=L'\0';
strHtml += strBuff;
} myHttpFile->Close();
mySession.Close(); return strHtml;
}
catch(CInternetException *e)
//catch(CException *e)
{
TCHAR err[1024];
e->GetErrorMessage(err,1024);
return L"";
}
}
“MultiByteToWideChar”: 不能将参数 3 从“wchar_t *”转换为“LPCSTR”
这行 int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
是不是还要转换一下.
的 源 文件 是什么 ,网页 点 “源文件”
我的修改时: char strBuff[2049] = {0}; while(nReadLength = myHttpFile->Read((void*)strBuff, 2048)){ } //这个2048的值调整一下,忘记了是2048还是2049。目的就是让他读取完全的数据,否则有些数据读取不完全就出现??,但是也能显示大部分中文。
我觉得出现??的原因是读取到的数据不完全。
//#include "stdafx.h"
#include "GetHtml.h"
#include "GetHtmlDlg.h"
#include <afxinet.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialog
{
public:
CAboutDlg();// 对话框数据
enum { IDD = IDD_ABOUTBOX }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:
DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CGetHtmlDlg 对话框
CGetHtmlDlg::CGetHtmlDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGetHtmlDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CGetHtmlDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_listbox_html);
}BEGIN_MESSAGE_MAP(CGetHtmlDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CGetHtmlDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CGetHtmlDlg::OnBnClickedButton2)
END_MESSAGE_MAP()
// CGetHtmlDlg 消息处理程序BOOL CGetHtmlDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 m_listbox_html.AddString(_T("test")); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}void CGetHtmlDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。void CGetHtmlDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CGetHtmlDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CGetHtmlDlg::OnBnClickedButton1()
{
CDialog::OnCancel();
}CStringA CGetHtmlDlg::gethtml(CString listurl)
{
try
{
CInternetSession mySession(NULL,0); //开始抓取网页验证登陆
CHttpFile* myHttpFile=NULL; char strBuff[2049] = {0};
//string strHtml;
CStringA strHtml; myHttpFile=(CHttpFile*)mySession.OpenURL(listurl,1,INTERNET_FLAG_TRANSFER_ASCII|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD); int nReadLength=0;
while(nReadLength = myHttpFile->Read((void*)strBuff, 2048))
{
strBuff[nReadLength]=L'\0';
strHtml += strBuff;
} myHttpFile->Close();
mySession.Close(); return strHtml;
}
catch(CInternetException *e)
//catch(CException *e)
{
TCHAR err[1024];
e->GetErrorMessage(err,1024);
return "";
}
}
LPWSTR ANSIConvertUNCOIDE(char* aText,int sourceCodePage)
{ int len=MultiByteToWideChar(sourceCodePage,NULL,aText,-1,NULL,0);
wchar_t *psText=new wchar_t[len+1];
memset(psText,0,len);
MultiByteToWideChar(sourceCodePage,NULL,aText,-1,psText,len+1);
//psText[len]='\0';
return psText;
}
void CGetHtmlDlg::OnBnClickedButton2()
{
UpdateData(TRUE);
CStringA str=gethtml(_T("http://www.chinaz.com"));
CStringW dd=ANSIConvertUNCOIDE(str.GetBuffer(),CP_UTF8); TRACE(dd);
m_listbox_html.AddString(dd);
UpdateData(FALSE);
AfxMessageBox(dd);
}
CStringA str=gethtml(_T("http://www.chinaz.com"));
CStringW dd=ANSIConvertUNCOIDE(str.GetBuffer(),CP_UTF8);
的 3个字节 被 你 断成 2段 了 ?
如 上次 读 了2 个 , 留下一个 与 后面的 乱 组合 了,
一定 要 保证 是 整数个 utf8
然后 转换。
按你的,确实成功了,不好意思,刚刚看错了,原来要用CStringA 和CStringW
按你的,确实成功了,不好意思,刚刚看错了,原来要用CStringA 和CStringW
如果你是直接拷贝过去的话,肯定是可以的。ansi工程对应的CString默认是CStringA ,unicode工程对应的CString是CStringW。自己可以跟踪去看vc的源码就知道了。