Форум программистов, компьютерный форум CyberForum.ru

Путаница с типами данных TCHAR и char. Какой тип данных выбрать? - C++

Восстановить пароль Регистрация
 
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 259
14.03.2014, 16:41     Путаница с типами данных TCHAR и char. Какой тип данных выбрать? #1
Я создавал тему в соседнем разделе:Не работает POST передача файла. Непонятки с TCHAR
Насколько я понял, то POST-данные в TCHAR отправлять нельзя, они должны бить char. Отсюда появляется вопрос - что делать? Как я понимаю, то предпочтительно использовать именно TCHAR в своем проекте. Только в конце концов получается что в момент, когда мне нужно будет отправить данные я все равно должен буду пользоваться чаром. Так что получается, мне теперь от поддержки юникод отказываться во всем проекте или как?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.03.2014, 16:41     Путаница с типами данных TCHAR и char. Какой тип данных выбрать?
Посмотрите здесь:

C++ Тип char.Signed/unsigned.Отличие типов данных.
[C++]enum и типы данных.Как задать тип значений явно,и какой тип будет при переполнении? C++
C++ Как проверить какой тип данных вводится?
Builder С++ и тип данных char C++ Builder
какой тип выбрать C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zer0mail
2187 / 1870 / 187
Регистрация: 03.07.2012
Сообщений: 6,656
Записей в блоге: 1
14.03.2014, 17:17     Путаница с типами данных TCHAR и char. Какой тип данных выбрать? #2
Может, POST понимает utf-8 ?
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 259
14.03.2014, 17:35  [ТС]     Путаница с типами данных TCHAR и char. Какой тип данных выбрать? #3
Вообще проблема в том что данные формы там в TCHAR, а файл я считываю в BYTE. Потом склеиваю данные. 1. данные формы TCHAR
2.Тело файла в BYTE
3. завершение данных формы TCHAR
Поэтому, наверное и веб-сервер на распознает данные. Если первый и третий пункт у меня чар то все нормально. В общем я не знаю как поступить. Тем более, что везде в проекте у меня TCHAR.
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,359
Завершенные тесты: 1
15.03.2014, 10:41     Путаница с типами данных TCHAR и char. Какой тип данных выбрать? #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от young_snake Посмотреть сообщение
Так что получается, мне теперь от поддержки юникод отказываться во всем проекте или как?
TCHAR - это или char, или wchar_t, в зависимости от настроек проекта.
Просто сконвертируйте строку из юникода в нужное представление,
которое требуется сервером. Либо укажите в своем запросе, что
используется UTF-16 (нормальный сервер должен "прожевать").
young_snake
6 / 6 / 2
Регистрация: 26.12.2011
Сообщений: 259
15.03.2014, 13:31  [ТС]     Путаница с типами данных TCHAR и char. Какой тип данных выбрать? #5
Я пробовал вот так преобразовывать, но в строке первой в конце какой-то мусор еще выводится.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
TCHAR frmdata1[] = L"-----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"file\"; filename=\"C:\\Windows\\temp\\hi.exe\"\r\nContent-Type: application/octet-stream\r\n\r\n";
     TCHAR frmdata2[] = L"\r\n-----------------------------7d82751e2bc0858--\r\n";
     TCHAR hdrs[] = L"Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 
     DWORD len1 = wcslen(frmdata1);
     DWORD len2 = wcslen(frmdata1);
 
     char *str1 = (char *)malloc(len1);
     char *str2 = (char *)malloc(len2);
     ZeroMemory(str1, len1);
     ZeroMemory(str2, len2);
 
     WideCharToMultiByte(CP_ACP, 0, frmdata1, wcslen(frmdata1), str1, wcslen(frmdata1), 0, 0);
     WideCharToMultiByte(CP_ACP, 0, frmdata2, wcslen(frmdata2), str2, wcslen(frmdata2), 0, 0);
     printf("%s",str1);
     printf("%s",str2);
     system("PAUSE");
     exit(0);
Добавлено через 23 минуты
Там я опечатался в пятой строчке. Но что интересно, я когда исправил код так

C++
1
2
DWORD len1 = wcslen(frmdata1)*sizeof(TCHAR);
DWORD len2 = wcslen(frmdata2)*sizeof(TCHAR);
то в выводе строк мусора не было. Я не понял почему так, ведь для новых строк cтипа har нужно указать их длину, а она равна количеству элементов в строке TCHAR а не количеству байт в ней.

Добавлено через 1 час 39 минут
Спасибо всем ответившим, функцию я реализовал, вот что у меня получилось:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <windows.h>
#include <sstream>
#include <shellapi.h>
#include <wininet.h>
 
#pragma comment(lib, "wininet")
 
int SendHttpFile(TCHAR *szFileName);
 
int _tmain(int argc, _TCHAR* argv[])
{
    
    SendHttpFile(L"C:\\Windows\\Temp\\hi.exe");
        
}
 
int SendHttpFile(TCHAR *szFileName)
{
 
    TCHAR szHost[] = L"127.0.0.1";
    TCHAR szURL[] = L"/upload/upload.php";
    TCHAR szUserAgent[] = L"Opera!";
    TCHAR szFrmdata_0[] = L"-----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n";
    TCHAR szFrmdata_2[] = L"\r\n-----------------------------7d82751e2bc0858--\r\n";
    TCHAR szHdrs[] = L"Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 
    TCHAR *szFrmdata_1;
    char *szBodyBegin, *szBodyEnd; 
    char *szForm;
    BOOL IsSent;
    HANDLE hFile;
    DWORD dwFileSize = 0, dwContentLength, dwRwBytes, dwLastError, dwLenFrmdata_1, dwLenBodyBegin, dwLenBodyEnd, dwLenForm;
    BYTE *ReadBuffer;
    
    std::stringstream ssErr;
    
    hFile = CreateFile(szFileName,  GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (!hFile)
    {
        dwLastError = GetLastError();
        MessageBoxA(NULL, (LPCSTR)L"Error", (LPCSTR)"Error", MB_OK);
        return 0;
    }
    dwFileSize = GetFileSize(hFile,  &dwFileSize);
    ReadBuffer = (BYTE*) malloc(dwFileSize);
    if(!ReadFile(hFile, ReadBuffer, dwFileSize, &dwRwBytes, NULL)) return 0;
    CloseHandle(hFile);
        
    //SendFile
    dwLenFrmdata_1 = wcslen(szFrmdata_0)*sizeof(TCHAR) + wcslen(szFileName) *sizeof(TCHAR);
    szFrmdata_1 = (TCHAR *)malloc(dwLenFrmdata_1);
    wsprintf(szFrmdata_1, szFrmdata_0, szFileName);
    dwLenBodyBegin = wcslen(szFrmdata_1)*sizeof(TCHAR);
    dwLenBodyEnd = wcslen(szFrmdata_2)*sizeof(TCHAR);
    szBodyBegin = (char *)malloc(dwLenBodyBegin);
    szBodyEnd = (char *)malloc(dwLenBodyEnd);
    ZeroMemory(szBodyBegin, dwLenBodyBegin);
    ZeroMemory(szBodyEnd, dwLenBodyEnd);
    WideCharToMultiByte(CP_ACP, 0, szFrmdata_1, -1, szBodyBegin, dwLenBodyBegin, 0, 0);
    WideCharToMultiByte(CP_ACP, 0, szFrmdata_2, -1, szBodyEnd, dwLenBodyEnd, 0, 0);
    dwLenForm = strlen(szBodyBegin) + strlen(szBodyEnd)  + dwFileSize;
    szForm = (char *)malloc(dwLenForm);
    ZeroMemory(szForm, dwLenForm);
    memcpy(szForm + (strlen(szBodyBegin)), ReadBuffer, dwFileSize); 
    memcpy(szForm, szBodyBegin, strlen(szBodyBegin)); 
    memcpy(szForm + dwFileSize+(strlen(szBodyBegin)), szBodyEnd , strlen(szBodyEnd));
    
    HINTERNET hSession = InternetOpen(szUserAgent,INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hSession)
    {
        /*
        dwLastError = GetLastError();
        ssErr << dwLastError;
        std::string strErr = ssErr.str();
        LPCSTR CstrErr = strErr.c_str();
        MessageBoxA(NULL, (LPCSTR)"InternetOpen Error", CstrErr, MB_OK);
        */
        return 0;
    }
   
    HINTERNET hConnect = InternetConnect(hSession, szHost, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
    if (!hConnect)
    {   
        /*
        dwLastError = GetLastError();
        ssErr << dwLastError;
        std::string strErr = ssErr.str();
        LPCSTR CstrErr = strErr.c_str();
        MessageBoxA(NULL, (LPCSTR)"InternetConnect Error", CstrErr, MB_OK);
        */
        return 0;
    }
    
    HINTERNET hRequest;
    hRequest = HttpOpenRequest(hConnect, L"POST", szURL, NULL, NULL, NULL , INTERNET_FLAG_RELOAD, 0);
    if (!hRequest)
    {   
        /*
        dwLastError = GetLastError();
        ssErr << dwLastError;
        std::string strErr = ssErr.str();
        LPCSTR CstrErr = strErr.c_str();
        MessageBoxA(NULL, (LPCSTR)"HttpOpenRequest Error", CstrErr, MB_OK);
        */
 
        return 0;
    }
 
    //dwLastError = GetLastError();
    IsSent = HttpSendRequest(hRequest, szHdrs, wcslen(szHdrs), szForm, dwLenForm);
    if (!IsSent)
    {           
        /*
        dwLastError = GetLastError();
        ssErr << dwLastError;
        std::string strErr = ssErr.str();
        LPCSTR CstrErr = strErr.c_str();
        MessageBoxA(NULL, (LPCSTR)"HttpSendRequest Error", CstrErr, MB_OK);
        */
        return 0;
    }
 
    InternetCloseHandle(hSession);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hRequest);
 
    return 1;
}
Yandex
Объявления
15.03.2014, 13:31     Путаница с типами данных TCHAR и char. Какой тип данных выбрать?
Ответ Создать тему
Опции темы

Текущее время: 16:09. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru