野指针嗷 2023-01-05 13:38 采纳率: 60%
浏览 66
已结题

从服务器获取数据,输出显示中文乱码&winsock的使用

本人刚接触网络编程不久,想用mfc做一个查询手机号归属地的小工具,已经找到了api接口,http-get请求也已经实现了,代码中的buffer变量就是返回的字符串,我试着把buffer打印到文件中,发现一切正常,汉字也能正常显示,但是当我把字符串用messagebox输出就会显示乱码,从网上找了各种各样的解决办法,包括转换编码,字符串格式等等,但都不起作用,求一个解决方案

下面是对话框cpp的代码(尝试处理字符串的部分已经注释掉)


#include "pch.h"
#include "framework.h"
#include "ToolKits.h"
#include "ToolKitsDlg.h"
#include "afxdialogex.h"
#include <winsock2.h>
#include <iostream>
#include <afxinet.h>
#include <locale>
#include <fstream>
#pragma comment (lib, "ws2_32.lib")
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CToolKitsDlg 对话框



CToolKitsDlg::CToolKitsDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_TOOLKITS_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CToolKitsDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CToolKitsDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_EN_CHANGE(IDC_EDIT1, &CToolKitsDlg::OnEnChangeEdit1)
    ON_BN_CLICKED(IDC_BUTTON1, &CToolKitsDlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CToolKitsDlg 消息处理程序

BOOL CToolKitsDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 将“关于...”菜单项添加到系统菜单中。

    // IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != nullptr)
    {
        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);        // 设置小图标

    // TODO: 在此添加额外的初始化代码
    setlocale(LC_ALL, "chs");


    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CToolKitsDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CToolKitsDlg::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
    {
        CDialogEx::OnPaint();
    }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CToolKitsDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}



void CToolKitsDlg::OnEnChangeEdit1()
{
    // TODO:  如果该控件是 RICHEDIT 控件,它将不
    // 发送此通知,除非重写 CDialogEx::OnInitDialog()
    // 函数并调用 CRichEditCtrl().SetEventMask(),
    // 同时将 ENM_CHANGE 标志“或”运算到掩码中。

    // TODO:  在此添加控件通知处理程序代码
}


void CToolKitsDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    CString mobile;
    GetDlgItem(IDC_EDIT1)->GetWindowTextW(mobile);
    MessageBox(mobile, 0, 0);
    char* get_ret = http_get_mobile(mobile);
    char* errp = "ERROR";
    if (strcmp(errp, get_ret) == 0)return;//判断是否返回ERROR,是则退出不解析
    

}

char* CToolKitsDlg::http_get_mobile(CString moblie)
{

    try
    {
        // 创建Internet连接
        CInternetSession session;
        // 发送GET请求
        CHttpFile* file = (CHttpFile*)session.OpenURL(
            _T("https://www.mxnzp.com/api/mobile_location/aim_mobile?mobile=1867800xxxx&app_id=lhkplhpxmxxxxx&app_secret=TE4zSWx0UG5MZXxxxxxxxxVDM1IrQT09"),
            1, INTERNET_FLAG_SECURE);
        // 读取服务器的响应
        char buffer[512];
                //    /*int nLen = MultiByteToWideChar(CP_ACP, 0, buffer, -1, NULL, 0);
        //    wchar_t* szWide = new wchar_t[nLen];
        //    MultiByteToWideChar(CP_ACP, 0, buffer, -1, szWide, nLen);
        //    CString str(szWide);
        //    delete[] szWide;
        //    ofstream ofile;
        //    ofile.open(L"out.txt");
        //    ofile << buffer << endl;
        //    ofile.close();
        //    MessageBox(str, L"str", 0);*/
        //    char* output;
        //    int len;
        //    wchar_t* out = (wchar_t*)malloc(len * sizeof(wchar_t));
        //    len = MultiByteToWideChar(CP_ACP, 0, buffer, -1, out, strlen(buffer));
        //    WideCharToMultiByte(CP_UTF8, 0, out, wcslen(out), output, len, NULL, NULL);
        //    int len1 = strlen(output);
        //    int wlen = MultiByteToWideChar(CP_UTF8, 0, output, len1, NULL, 0);
        //    wchar_t* wstr = new wchar_t[wlen + 1];
        //    MultiByteToWideChar(CP_UTF8, 0, output, len1, wstr, wlen);
        //    wstr[wlen] = 0;
        //    CString str(wstr);
        //    delete[] wstr;
                //      MessageBox(str);

        }
        // 关闭文件并结束Internet连接
        file->Close();
        session.Close();
    }
    catch (CInternetException* e)
    {
        CString err;
        err.Format(L"Internet exception:%d", e->m_dwError);
        MessageBox(err);
        e->Delete();
    }

    return nullptr;
}

还有一个问题就是:我在这个项目中使用winsock库发送get请求总是不成功,当我连接到目标服务器的80接口时,返回信息提示301 moved permanently;当我连接到443端口,又会提示400 The plain HTTP request was sent to HTTPS port,而用CInternetSession类发送GET请求就能成功,这是啥原因?

  • 写回答

3条回答 默认 最新

  • churuxu 2023-01-05 16:16
    关注

    一般HTTP接口传输字符串都是utf8编码,转换成unicode再显示

    WCHAR wbuf[512];
    MultiByteToWideChar(CP_UTF8, 0, 源字符串, -1, wbuf, 512);
    MessageBox(wbuf, L"标题", MB_OK);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月5日
  • 已采纳回答 1月5日
  • 创建了问题 1月5日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改