2016-10-26 2 views
1

좋아요, 저는 C++ 사람이 아닙니다. 코드를 읽고 다른 언어를 기반으로 추측을하고 있기 때문에 아마도 이것은 저주받을 것입니다. 당신이 볼 수 있듯이,이 프로그램은 INI 파일을 읽고, 그래서 작은 변화 하나 개의 솔루션)ostringstream에서 TCHAR 사용

... 

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

을 컴파일하려면, 쓰기 szAPI API 키, 그리고 그것을 ostringstream (buf)에서 사용해야합니다. PHP에서 POST 변수를 보면 ini 파일에 32 자 길이의 영숫자 문자열을 제공하고자 할 때 8 자리 16 진수 "0019EEE0"을 제공합니다. tchar을 문자열로 변환하는 방법을 살펴 보았지만 실제로는 아무 것도 작동하지 않았습니다. 내가 헤더 파일에

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

을 넣을 때 아무 일도 발생하지 않습니다, 변수가 문자열로 변환해야 잘 때 내가 그것을 둘 때, 그것은 오류 (기호 타입 정의 오버로드 할 수 없음)

내가 사용하는 것이 TCHAR을 사용하여 헤더를 만들었지 만 API 헤더 바로 아래의 헤더에 이미지를 삽입하는 코드로 작업하는 방법을 알지 못합니다.

나는이 일을하는 데 일종의 상실감이있다. 생성 된 ini 파일과 exe 파일을 사용하여 PHP에서 zip 파일을 생성 한 다음 내 서버로 누가 업로드하는지 추적 할 수 있도록 API 키가 ini 파일에 있어야합니다.

아이디어가 있으면 감사드립니다.

+0

'TCHAR'의 목적은 Windows 9x 용 프로그램을 빌드하여 제한된 지역 문자 세트로 Windows 9x에서 작동하도록하는 것이 었습니다. 이 추악한 매크로 기반 장치는 유니 코드 용 레이어 (Layer for Unicode)의 도입으로 2000 년에 폐기되었습니다. 몇 년 후, Windows 9x는 더 이상 존재하지 않았습니다. Windows 9x를 대상으로하고 있으며 유니 코드 용 레이어를 사용하지 않는 것이 좋은 이유가 확실합니까? 그렇지 않다면 어째서 지구에서'차 '를 사용하고 있습니까? –

+0

현대 윈도우에서는 와이드 문자 ('wchar_t' 기반 문자열과 함수)를 사용하고이를 사용합니다. –

+0

Windows API 래퍼 이외에 TCHAR을 사용하지 마십시오. ANSI 문자 인코딩과 와이드 문자 사이를 전환하도록 설계되었습니다. C stdlib에 관한 한 TCHAR는 존재하지 않습니다. 소프트웨어가 사용하는 문자 인코딩을 결정하고 적절한 표준 라이브러리 기능을 사용하십시오. –

답변

1
당신이 언급 한 것처럼

, 윈도우 사용 UTF16하지만 인터넷 기능 작업을 시작했다 UTF8을 기대하십시오.

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

이 변환은 항상 작동하지 않습니다.

일반적으로 UTF16을 UTF8로 변환하려면 WideCharToMultiByte을 사용해야합니다.

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

고맙습니다. utf16은 모든 상황에서 정상적으로 작동하는 것처럼 보였지만, 나는 이것을 바꿔서 작동합니다. PHP 파일 업로드를 위해 imagedata에 헤더 파일 이름을 부여해야했습니다. – Alice

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

... 
0

당신이는 Win32와 코드를 사용하려는 때문에, 가장 깨끗한 방법은 문자열 조작이 UCS-16 공간에서 작동하도록하는 대신 std::ostringstreamstd::wostringstream을 사용하는 것입니다 .

또 다른 해결 방법은 ANSI 기능의 문제가 응용 프로그램에서 문제가되지 않는 경우 Win32 ANSI 함수를 사용하여 멀티 바이트 공간 (예 : GetPrivateProfileStringA())에서 작업하는 것입니다.

관련 문제