У меня есть следующий код для загрузки некоторых файлов rss с серверов, но пока я просто получаю неполную версию своего файла rss. (?) Код выглядит следующим образом —
#include<iostream>
#include<conio.h>
#include<stdio.h>
#include<string>
#include<cstring>
#include<wininet.h>
using namespace std;
const int _SIZE = 307200;
int WEB_GET_DATA(char* WEB_URL){
HINTERNET WEB_CONNECT = InternetOpen("Default_User_Agent",INTERNET_OPEN_TYPE_PRECONFIG,NULL, NULL, 0);
if(!WEB_CONNECT){
cout<<"Connection Failed or Syntax error";
return 0;
}
HINTERNET WEB_ADDRESS = InternetOpenUrl(WEB_CONNECT,WEB_URL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 0);
if(!WEB_ADDRESS){
cout<<"ERROR...\n";
return 0;
}
char _DATA_RECIEVED[_SIZE];
DWORD NO_BYTES_READ = 0;
while(InternetReadFile(WEB_ADDRESS,_DATA_RECIEVED,_SIZE,&NO_BYTES_READ)&&(NO_BYTES_READ)){
cout<<_DATA_RECIEVED;
}
InternetCloseHandle(WEB_ADDRESS);
InternetCloseHandle(WEB_CONNECT);
return 0;
}
int main(){
WEB_GET_DATA("http://themoneyconverter.com/rss-feed/AED/rss.xml");
getch();
return 0;
}
Я получаю только почти половину моего файла, а не с самого начала, но мой вывод, кажется, начинается где-то между файлом и затем заканчивается.
Так куда я иду не так? Я проверил, что мой rss-файл, по крайней мере, будет размером 30 КБ. Таким образом, я дал _SIZE const 307200 (300 КБ), и все же он не работает? Пожалуйста, помогите мне.
Попробуйте это вместо этого:
int WEB_GET_DATA(char* WEB_URL)
{
HINTERNET WEB_CONNECT = InternetOpen("Default_User_Agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!WEB_CONNECT)
{
cout << "Connection Failed or Syntax error" << endl;
return 0;
}
HINTERNET WEB_ADDRESS = InternetOpenUrl(WEB_CONNECT, WEB_URL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 0);
if (!WEB_ADDRESS)
{
cout << "ERROR..." << endl;
InternetCloseHandle(WEB_CONNECT);
return 0;
}
DWORD DATA_SIZE = _SIZE;
char *_DATA_RECIEVED = new char[DATA_SIZE];
DWORD NO_BYTES_READ = 0;
do
{
if (InternetReadFile(WEB_ADDRESS, _DATA_RECIEVED, DATA_SIZE, &NO_BYTES_READ))
{
if (NO_BYTES_READ == 0)
break;
cout << string(_DATA_RECIEVED, NO_BYTES_READ);
}
else
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
cout << "Read error" << endl;
break;
}
delete[] _DATA_RECIEVED;
DATA_SIZE += _SIZE;
_DATA_RECIEVED = new char[DATA_SIZE];
}
}
while (true);
InternetCloseHandle(WEB_ADDRESS);
InternetCloseHandle(WEB_CONNECT);
return 0;
}
Прежде всего, проблема, с которой вы столкнулись, заключается в том, что вы перезаписываете один и тот же буфер и не очищаете данные перед каждым вызовом InternetReadFile. Вы также не очистили буфер перед первым вызовом. Вы тогда бросаете потенциально искаженный беспорядок строки и памяти в cout. Это очень плохо.
Быстрое решение было бы сделать это:
BYTE _DATA_RECIEVED[_SIZE]; // BYTE is a char, but its clearer now its not guaranteed to be a string!
BOOL ret = TRUE;
DWORD NO_BYTES_READ = 0;
while(ret){
memset(_DATA_RECIEVED, 0, _SIZE); // clear the buffer
ret = InternetReadFile(WEB_ADDRESS,_DATA_RECIEVED,_SIZE,&NO_BYTES_READ);
if(NO_BYTES_READ > 0)
cout<<_DATA_RECIEVED;
}
Это не самый элегантный способ сделать это (далеко не так), но, по крайней мере, вы должен получить данные, которые вы ожидаете обратно.
Помните, InternetReadFile передает обратно буфер данных, а не обязательно строку! Это может быть изображение, мусор, и даже если это строка, в вашем случае у него не будет нулевого байта, чтобы закрыть его. InternetReadFile читает необработанные байты, а не текст.
Более элегантное решение может Начните как это:
std::string resultRss;
BYTE _DATA_RECIEVED[_SIZE];
DWORD NO_BYTES_READ = 0;
while(InternetReadFile(WEB_ADDRESS,_DATA_RECIEVED,_SIZE,&NO_BYTES_READ)){
resultRss.append((char*)_DATA_RECIEVED, NO_BYTES_READ); //doesn't matter about null-byte because we are defining the number of bytes to append. This also means we don't NEED to clear the memory, although you might want to.
}
//output final result
cout << resultRss;
Кроме того, как добавил комментатор, вам нужно отложить ALLCAPS для переменных.
Надеюсь это поможет.