2016-10-26 4 views
1

Okay, ich bin nicht wirklich eine C++ Person, und dies wird wahrscheinlich zur Verdammnis verdammt werden, da ich gerade den Code lese und Vermutungen basierend auf den anderen Sprachen mache, die ich kenne (schlecht weiß ich, aber ich wollen einfach nur eine Lösung mit einer kleinen Änderung) späterVerwenden Sie TCHAR in ostringstream

... 

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()); 

... viele Zeilen kompilieren ...

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

so, wie Sie sehen können, ist das Programm eine iNI-Datei Lesen, Schreiben der API-Schlüssel zu szAPI, und dann muss ich es im ostringstream (buf) verwenden. Wenn ich mir die POST-Variablen in PHP ansehe, gibt es mir ein 8-stelliges Hexadezimal "0000EEE0", wenn ich möchte, dass es eine 32 Zeichen lange alphanumerische Zeichenfolge in der Ini-Datei gibt. Ich habe mir angeschaut, wie man Tchar in String umwandeln kann, aber nichts hat wirklich für mich funktioniert. Wenn ich

setzen
#ifndef UNICODE 
    typedef std::string szAPI; 
#else 
    typedef std::wstring szAPI; 
#endif 

in der Header-Datei, passiert nichts, und wenn ich es in Ordnung zu bringen, wenn die Variable in einem String umwandeln sollte, es Fehler

(Symbol kann nicht mit einem typedef überlastet werden) würde ich TCHAR, um die Header zu machen, aber ich würde nicht wissen, wie man mit dem Code arbeitet, um das Bild in die Header direkt unter dem API-Header zu setzen.

So bin ich etwas ratlos mit dieser Arbeit. Ich brauche den API-Schlüssel, um in der Ini-Datei zu sein, so dass ich eine PHP-komprimierte Datei mit einer generierten Ini-Datei und einer Exe erstellen kann, dann sende ich sie aus, damit ich verfolgen kann, wer was auf meinen Server hochlädt.

Wenn Sie irgendwelche Ideen haben, danke.

+0

Der Zweck von 'TCHAR' war es, ein Programm für Windows 9x zu erstellen, so dass es in Windows 9x für einen begrenzten lokalen Zeichensatz funktionieren würde. Dieses hässliche makrobasierte Gerät wurde im Jahr 2000 durch die Einführung von Layer für Unicode veraltet. Dann, einige Jahre später, war Windows 9x nicht mehr. Sind Sie sicher, dass Sie auf Windows 9x abzielen und dass Sie einen guten Grund haben, den Layer nicht für Unicode zu verwenden? Wenn nicht, warum benutzen Sie 'TCHAR'? –

+0

In modernen Windows verwenden Sie einfach breite Zeichen ('wchar_t' basierte Strings und Funktionen) und damit fertig sein. –

+0

Verwenden Sie TCHAR nicht mit anderen als Windows-API-Wrappern. Es wurde entwickelt, um zwischen ANSI-Zeichencodierung und Breitzeichen zu wechseln. Soweit es die C stdlib betrifft, existiert TCHAR nicht. Entscheiden Sie, welche Zeichencodierung Ihre Software verwendet und verwenden Sie die entsprechenden Standardbibliotheksfunktionen. –

Antwort

1

Wie Sie bemerkt haben, verwenden UTF16 Windows, aber Internet-Funktionen erwarte UTF8.

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

Diese Konvertierung wird nicht immer funktionieren.

Im Allgemeinen müssen Sie WideCharToMultiByte verwenden, um UTF16 in UTF8 zu konvertieren.

Da Sie Visual Studio verwenden, können Sie ATL-Klassen aus praktischen Gründen verwenden.

sA enthält jetzt UTF8-Daten. Verwenden Sie wie folgt vor:

my_ostringstream << sA.GetString(); 

oder

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

Vielen Dank dafür. Das utf16 schien in allen Situationen gut zu funktionieren, aber ich bin dazu gewechselt und es funktioniert auch. Ich musste den Imagedaten einen Dateinamen in den Headern geben, damit die PHP-Datei hochgeladen werden kann. – Alice

0

Okay, das ist wahrscheinlich nicht die beste Art und Weise, Dinge zu tun, aber ich habe stundenlang versucht, und es begann die Arbeit mit

... 

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); 

... 
0

Da Sie Ihren Code zu verwenden, um mit Win32 beabsichtigen, wäre der sauberste Weg std::wostringstream statt std::ostringstream zu verwenden, um String-Manipulationen arbeiten auf UCS-16 Platz zu machen . Eine andere Problemumgehung besteht darin, Win32-ANSI-Funktionen zu verwenden, um Multibyte-Speicherplatz (z. B. GetPrivateProfileStringA()) zu arbeiten, wenn diese lästigen i18n-Probleme in ANSI-Funktionen in Ihrer Anwendung nicht auftreten.

Verwandte Themen