Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.06.2010, 16:30   #1
Gtx541
Пользователь
 
Регистрация: 20.05.2010
Сообщений: 24
Вопрос InternetReadFile - проблемы с кодировками

Программа получает html-код веб-страницы (http://msdn.com/ru-ru/default.aspx).
Получение файла происходит без ошибок.
Латиница, большинство спец.символов и цифры отображаются прекрасно, а вместо русских букв выводится непонятно что.
Вместо строки:
"Новости Русского MSDN"
в массиве char-ов сохраняется такое:
"Новости Р*СѓСЃСЃРєРѕРіРѕ MSDN"

Как с этим бороться?

Вот код:

Код:
#include <Windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")

bool WriteToFile(char * text, unsigned int len);

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	const DWORD fullTextLength = 300000;
	char html [fullTextLength];

	// открываем интернет-сессию
	HINTERNET hInternet;
	hInternet = InternetOpenA(
		"Internet Explorer",
		INTERNET_OPEN_TYPE_PRECONFIG,
		NULL,
		NULL,
		NULL
		);
	if (hInternet != NULL)
	{
		LPSTR lpszUrl = "http://msdn.com/ru-ru/default.aspx";
		LPSTR lpszHeaders = NULL;
		DWORD dwHeadersLength = NULL;
		// INTERNET_FLAG_NO_UI - Disables the cookie dialog box
		// INTERNET_FLAG_RELOAD - не загружать из кэша, загружать из инета
		DWORD dwFlags = INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;

		// открываем URL-адрес
		HINTERNET hFile;
		hFile = InternetOpenUrlA(
			hInternet,
			lpszUrl,
			lpszHeaders,
			dwHeadersLength,
			dwFlags,
			NULL
			);

		if (hFile != NULL)
		{
			DWORD lpdwNumberOfBytesRead;
			char buf[fullTextLength];

			SecureZeroMemory(html, fullTextLength);

			int jjj=0;

			do
			{
				// обнуляем буфер перед его использованием
				SecureZeroMemory(buf, fullTextLength);
				InternetReadFile(hFile, buf, fullTextLength-1, &lpdwNumberOfBytesRead);

				// это я так строки копирую
				for (DWORD ii=0; ii<lpdwNumberOfBytesRead; ii++, jjj++)
					html[jjj] = buf[ii];
			}
			while (lpdwNumberOfBytesRead != 0);

			//
			//
			//
			//
			//
			// сейчас весь html-код страницы содержится в массиве html
			// но вместо русских букв там отображается какая-то "муть"
			//
			// ЗАДАЧА: сделать так, чтобы в массиве html отображались русские буквы,
			// а не вот это: "Новости Р*СѓСЃСЃРєРѕРіРѕ"
			//
			//
			//
			//
			//

			// это так, для отладки...
			html[1000] ='\0';
			MessageBoxA(NULL, html, "Первые 1000 символов html-страницы", MB_OK);

			// пишем полученный html-файл в файл на жестком диске
			// из char-а в файл
			WriteToFile(html, lstrlenA(html));

			InternetCloseHandle(hFile);
		}
		else
		{
			MessageBox(NULL, L"Error", L"Error", MB_ICONERROR);
		}

		InternetCloseHandle(hInternet);
	}
	else 
	{
		MessageBox(NULL, L"Error", L"Error", MB_ICONERROR);
	}

	return 0;
}

// Тут ничего интересного нет
// Просто запись текста в файл
bool WriteToFile(char * text, unsigned int len)
{
	HANDLE hFile;
	LPCSTR lpFileName = "C:\\FromInet.txt";
	DWORD dwDesiredAccess = GENERIC_WRITE;
	DWORD dwShareMode = 0;
	LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
	DWORD dwCreationDisposition = CREATE_ALWAYS;
	DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
	HANDLE hTemplateFile = NULL;

	// сначала нужно создать файл
	hFile = CreateFileA(
		lpFileName,
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
		);

	if (hFile != INVALID_HANDLE_VALUE)
	{
		LPCVOID lpBuffer = text;
		DWORD nNumberOfBytesToWrite = len;
		DWORD lpNumberOfBytesWritten;
		LPOVERLAPPED lpOverlapped = NULL;

		// теперь непосредственная запись в файл
		BOOL b = WriteFile(
			hFile,
			lpBuffer,
			nNumberOfBytesToWrite,
			& lpNumberOfBytesWritten,
			lpOverlapped
			);

		// закрыть файл для записи
		CloseHandle(hFile);

		if (b == FALSE)
		{
			MessageBoxA(NULL, "Не удалось записать данные в файл", "Ошибка", MB_OK | MB_ICONERROR);
			return false;
		}
		else return true;
	}
	else
	{
		MessageBoxA(NULL, "INVALID_HANDLE_VALUE", "Ошибка", MB_ICONERROR | MB_OK);
		return false;
	}
	return false;
}

Вот результат работы программы:
Gtx541 вне форума Ответить с цитированием
Старый 06.06.2010, 22:03   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Текст в UTF-8, в WinApi есть MultiByteToWideChar для перекодирования в UTF-16, потом MessageBoxW. А если всё-таки надо в ANSI, то можно потом WideCharToMultiByte.
Somebody вне форума Ответить с цитированием
Старый 07.06.2010, 13:36   #3
Gtx541
Пользователь
 
Регистрация: 20.05.2010
Сообщений: 24
По умолчанию

Как долго я искал эту функцию!
Спасибо! Проблема решена.
Gtx541 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблемы с кодировками в английской Windows Altera Windows 6 18.10.2009 08:30
Проблема з кодировками! hoza_syl PHP 3 10.10.2009 15:10
Банальные проблемы с кодировками и наборами символов. Killer_djon PHP 5 02.06.2009 14:38
Проблема с кодировками igroman Общие вопросы C/C++ 9 25.01.2009 22:25
Проблемы с кодировками Анси и Юникод HunterMan Win Api 4 31.05.2008 00:41