2013-07-26 4 views
1

을받지 I 서버에서 일부 RSS 파일을 다운로드하려면 다음 코드를 가지고 있지만, 지금까지 난 그냥 내 RSS 파일의 불완전한 버전을지고있어 다음과 같이 코드입니다. (?) -의 InternetReadFile는 전체 파일

#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 파일이 적어도 30kb 크다는 것을 확인했다. 그래서 나는 _SIZE const 307200 (300kb)를주고 여전히 작동하지 않습니까? 도와주세요.

+0

키핑 규칙과 표준을 읽고 당신은 더 나은 해답을 얻을 수 있도록 코드를 쉽게 할 것이다. UPPER_CASE 식별자는 대개 매크로에만 사용되며 전역 범위에서 밑줄로 시작하는 식별자는 컴파일러 용도로 예약되어 있습니다. –

+0

좋습니다. 명심하십시오. 하지만 내 문제를 도와 줄 수있어? –

답변

-1

먼저, Internet Explorer의 각 호출 전에 데이터를 지우지 않고 동일한 버퍼를 덮어 쓰는 것이 문제입니다. 또한 첫 번째 호출 전에 버퍼를 지우지 않았습니다. 당신은 그 때 문자열과 기억의 잠재적으로 왜곡 된 엉망을 한쪽에 던지고 있습니다. 이건 정말 나빠.

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은 반드시 데이터 버퍼를 전달합니다. 반드시 문자열이 아니어야합니다! 그것은 이미지, 쓰레기, 그리고 경우에도 그것은 문자열입니다, 귀하의 경우에는, 그것은 그것을 없애 null 바이트가 실 거예요. 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을 해고해야합니다.

희망이 도움이됩니다.

+1

자네가 무슨 뜻인지 알 겠어. 하지만 두 번째 접근법을 컴파일하면 55 C : \ Users \ Maximus7 \ Documents \ Untitled1.cpp : 24 오버로드 된 'append (BYTE [307200], DWORD &)'호출이 모호합니다. 이게 뭐야? –

+1

이상한 측면에서 첫 번째 접근 방식은 여전히 ​​나에게 동일한 결과를 제공하고 있습니까? 또한 흥미로운 점을 발견했습니다. 각'\ n "에 대해''C OUT << _ DATA_RECIEVED' 이후에 포함 시켰습니다. 그것은 내 문제와 관련이 있습니까? –

+1

죄송합니다. 코드를 약간 수정했습니다. 나는 line resultRss.append ((char *) _ DATA_RECIEVED, NO_BYTES_READ)를 변경했다. . 바이트 (unsigned char *)로 정의하므로 _DATA_RECIEVED를 (char *)로 캐스팅해야합니다. 또는 BYTE를 CHAR acain으로 바꿀 수 있습니다. 두 번째 예제는 데이터를 화면에 출력하는 것뿐만 아니라 데이터를 저장하는 것과 같은 더 강력한 대안을 생각하게하는 것입니다. –

0

대신보십시오 : 마음에

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; 
} 
+0

미안하지만 작동하지 않습니다. 나는 약 30kb 크기의 다른 파일을 시도하고 출력에 누락 된 데이터의 동일한 오류를 모두 내게 주었다. –

+0

데이터에 null 문자가 있는지 확인 했습니까? 데이터를 화면에 출력하는 대신 파일에 저장하려고 시도 했습니까? 화면 출력에서 ​​2 진 데이터를 표시 할 수 없습니다. 따라서 화면 결과가 아닌 실제 데이터를 확인하십시오. –