在ostringstream中使用TCHAR

时间:2016-10-26 01:03:41

标签: c++ std tchar

好吧,我不是一个真正的C ++人,这可能会被贬低到诅咒,因为我只是阅读代码并根据我所知道的其他语言进行猜测(我知道的很糟糕,但我只是想要用一个小的改动来编译一个解决方案)

...

BOOL uploadFile(HWND hwnd, LPCTSTR fileName)
{
    const TCHAR* UPLOAD_SERVER  = _T("myhostname.com"); //not my real hostname, just for this question
    const TCHAR* UPLOAD_PATH    = _T("/upload.php"); 
    const TCHAR* CONFIG_FILE    = _T("config.ini");
    const TCHAR* API_KEY = _T("key");

    TCHAR szUploadServer[MAX_PATH];
    TCHAR szUploadPath[MAX_PATH];
    TCHAR szAPI[MAX_PATH];
    TCHAR szWD[MAX_PATH];

    const char*  sBoundary = "----BOUNDARYBOUNDARY----";        // boundary
    const char   sCrLf[]   = { 0xd, 0xa, 0x0 };                 // ‰üs(CR+LF)
    const TCHAR* szHeader  = 
        _T("Content-type: multipart/form-data; boundary=----BOUNDARYBOUNDARY----");

    _tgetcwd(szWD, sizeof(szWD) / sizeof(TCHAR));
    _tcsncat(szWD, _T("\\"), 1);
    _tcsncat(szWD, CONFIG_FILE, _tcslen(CONFIG_FILE));

    GetPrivateProfileString(_T("Configuration"), _T("SERVER"), UPLOAD_SERVER, szUploadServer, sizeof(szUploadServer) / sizeof(TCHAR), szWD);
    GetPrivateProfileString(_T("Configuration"), _T("PATH"), UPLOAD_PATH, szUploadPath, sizeof(szUploadPath) / sizeof(TCHAR), szWD);
    GetPrivateProfileString(_T("Configuration"), _T("API"), API_KEY, szAPI, sizeof(szAPI) / sizeof(TCHAR), szWD);
    std::ostringstream  buf;

    // -- "api" part
    buf << "--";
    buf << sBoundary;
    buf << sCrLf;
    buf << "content-disposition: form-data; name=\"api\"";
    buf << sCrLf;
    buf << sCrLf;
    buf << szAPI;
    buf << sCrLf;
    // -- "imagedata" part
    buf << "--";
    buf << sBoundary;
    buf << sCrLf;
    buf << "content-disposition: form-data; name=\"imagedata\"";
    buf << sCrLf;
    //buf << "Content-type: image/png"; // ˆê‰ž
    //buf << sCrLf;
    buf << sCrLf;

    // –{•¶: PNG ƒtƒ@ƒCƒ‹‚ð“Ç‚Ýž‚Þ
    std::ifstream png;
    png.open(fileName, std::ios::binary);
    if (png.fail()) {
        MessageBox(hwnd, _T("PNG open failed"), szTitle, MB_ICONERROR | MB_OK);
        png.close();
        return FALSE;
    }
    buf << png.rdbuf();     // read all & append to buffer
    png.close();

    // ÅŒã
    buf << sCrLf;
    buf << "--";
    buf << sBoundary;
    buf << "--";
    buf << sCrLf;

    // ƒƒbƒZ[ƒWŠ®¬
    std::string oMsg(buf.str());

......很多行后来......

HttpSendRequest(hRequest,
                szHeader,
                lstrlen(szHeader),
                (LPVOID)oMsg.c_str(),
                (DWORD) oMsg.length())

因此,正如您所看到的,程序正在读取一个ini文件,将API密钥写入szAPI,然后我需要在ostringstream(buf)中使用它。当我在PHP中查看POST变量时,它给了我一个8位十六进制&#34; 0019EEE0&#34;当我希望它在ini文件中提供一个32个字符长的字母数字字符串时。我查看了如何将tchar转换为字符串,但没有什么对我有用。当我把

#ifndef UNICODE  
  typedef std::string szAPI; 
#else
  typedef std::wstring szAPI; 
#endif
在头文件中

没有任何反应,当我在变量转换为字符串时将其正确放置时,它会出错(符号不能用typedef重载)

我会使用TCHAR制作标题,但我不知道如何使用代码将图像放在api标题正下方的标题中。

所以我在做这项工作时感到很茫然。我需要API密钥在ini文件中,所以我可以在php中使用生成的ini文件和exe构建一个zip,然后将其发送出去,这样我就可以跟踪谁将什么内容上传到我的服务器。

如果您有任何想法,谢谢。

3 个答案:

答案 0 :(得分:1)

如您所知,Windows使用UTF16,但互联网功能需要UTF8。

char api[MAX_PATH];
wcstombs(api, szAPI, wcslen(szAPI) + 1);

此转换并不总是有效。

通常,您必须使用WideCharToMultiByte将UTF16转换为UTF8。

由于您使用的是Visual Studio,因此可以使用ATL类。

#include <AtlStr.h>

...
CStringA sA = CW2A(szAPI, CP_UTF8);

sA现在包含UTF8数据。使用方法如下:

my_ostringstream << sA.GetString();

HttpSendRequest(hRequest, szHeader, lstrlen(szHeader),
    (LPVOID)sA.GetString(), (DWORD)sA.GetLength());

答案 1 :(得分:0)

好吧,这可能不是最好的做事方式,但我已经尝试了几个小时并开始使用

...

GetPrivateProfileString(_T("Configuration"), _T("SERVER"), UPLOAD_SERVER, szUploadServer, sizeof(szUploadServer) / sizeof(TCHAR), szWD);
GetPrivateProfileString(_T("Configuration"), _T("PATH"), UPLOAD_PATH, szUploadPath, sizeof(szUploadPath) / sizeof(TCHAR), szWD);
GetPrivateProfileString(_T("Configuration"), _T("API"), API_KEY, szAPI, sizeof(szAPI) / sizeof(TCHAR), szWD);
char api[MAX_PATH];
wcstombs(api, szAPI, wcslen(szAPI) + 1);

...

答案 2 :(得分:0)

由于您打算在Win32中使用您的代码,最简单的方法是使用std::wostringstream而不是std::ostringstream来使字符串操作在UCS-16空间上运行。

另一种解决方法是使用Win32 ANSI函数处理多字节空间(例如GetPrivateProfileStringA()),如果ANSI函数中那些令人讨厌的i18n问题在您的应用程序中没有问题。