比如,我抓取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="站长之家(中国站长??为个人站长与企业网络提供全面的站长资讯、最新最全的源代码程序下载、海量建站素材、强大的搜索优化辅助工具、网络产品设计与运营理念以及一站式网络解决方案,十年来我们一直致力为中文网站提供动力??>注意后面的问号

解决方案 »

  1.   

    希望对你有提示由于网络间一般用UTF8表示字串(ANSI字串- (char < 128)本身已经符合UTF8编码规则),所以ANSI字符不会乱码,而一个汉字的传统表示需要两个字符,而在wchar_t宽字符串中只需一个字符表示。一个汉字用UTF8表示通常占用3个BYTE, 如:
             你  --〉0xe4, 0xbd, 0xa0
             好  --> 0xe5, 0xbd, 0x21
      

  2.   

    gSoap在封装XML包时,在进行utf8字符转换时:
       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
      

  3.   


    转换后部分位置出现?是因为对应位置的UTF8字符,没有合适的Unicode字符对应
      

  4.   

    也就是将函数
    wchar_t* CzzbaoApp::Utf8ToUnicode(char *szU8)//utf8转unicode的参数改为宽字符串wchar_t*
      

  5.   

    "<title>站长之家 - 中国站长??- 站长资讯 | 我们致力于为中文网站提供动力??/title>"源码 是什么 ?
      

  6.   

    用下面的函数抓住这个网址的html代码,然后用楼主的哪个函数转换成unicode
    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"";
        }
    }
      

  7.   

    如果我用这个函数抓取gb2012的网页,转不用转换也全部正确.utf-8转换就出现?号
      

  8.   

    改成 wchar_t* CzzbaoApp::Utf8ToUnicode(wchar_t *szU8) 后,出现
    “MultiByteToWideChar”: 不能将参数 3 从“wchar_t *”转换为“LPCSTR”
    这行 int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
    是不是还要转换一下.
      

  9.   

    我是说 “"<title>站长之家 - 中国站长??- 站长资讯 | 我们致力于为中文网站提供动力??/title>"
    的 源 文件 是什么 ,网页 点 “源文件”
      

  10.   

    以前我也遇到过这个问题,已经正确的编码转换后,显示出来中文了,但是就是存在一些问号。后面改了下读取数据的代码就Ok了,不知道你是不是这种情况。 
    我的修改时: char strBuff[2049] = {0};  while(nReadLength = myHttpFile->Read((void*)strBuff, 2048)){ } //这个2048的值调整一下,忘记了是2048还是2049。目的就是让他读取完全的数据,否则有些数据读取不完全就出现??,但是也能显示大部分中文。
    我觉得出现??的原因是读取到的数据不完全。
      

  11.   

    <title>站长之家 - 中国站长站 - 站长资讯 | 我们致力于为中文网站提供动力!</title>
      

  12.   

    直接上源码和图片吧。// GetHtmlDlg.cpp : 实现文件
    //#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);
    }
      

  13.   

    我觉得是先使用ansi接收(CStringA ),然后utf8编码转换位宽字符串CStringW 。
    CStringA str=gethtml(_T("http://www.chinaz.com"));
    CStringW dd=ANSIConvertUNCOIDE(str.GetBuffer(),CP_UTF8);
      

  14.   

    是不是 读的时候, utf8
    的 3个字节 被 你 断成 2段 了 ?
    如 上次 读 了2 个 , 留下一个 与 后面的 乱 组合 了, 
    一定 要 保证 是 整数个 utf8
    然后 转换。 
      

  15.   

    18楼,这个代码在unicode下不行哦
      

  16.   

    vc2008默认编码环境unicode不是宽字节
      

  17.   

    怎么不得?是你自己的设置有问题吧,我的vs2008 unicode工程是Ok的。
      

  18.   


    按你的,确实成功了,不好意思,刚刚看错了,原来要用CStringA 和CStringW
      

  19.   


    按你的,确实成功了,不好意思,刚刚看错了,原来要用CStringA 和CStringW
    如果你是直接拷贝过去的话,肯定是可以的。ansi工程对应的CString默认是CStringA ,unicode工程对应的CString是CStringW。自己可以跟踪去看vc的源码就知道了。