jpgファイルのダウンロード方法を解説!

このQ&Aのポイント
  • WWWサーバー上のjpgファイルをダウンロードするプログラムを作成していますが、ダウンロードしたファイルの中身が見えません。どこが問題なのか教えてください。
  • Windows VistaとVC++ 2005 EEを使用して、WWWサーバー上のjpgファイルをダウンロードするプログラムを作成しています。しかし、ダウンロードしたファイルを開くと中身が表示されません。どうすればファイルの中身を確認できるようになるのでしょうか?
  • WWWサーバー上のjpgファイルをダウンロードするプログラムを作成していますが、ダウンロードしたファイルを開くと中身が正しく表示されません。解決策を教えてください。
回答を見る
  • ベストアンサー

jpgファイルのダウンロード

WWWサーバー上にあるjpgファイルを指定してそれをダウンロードするプログラムをつくっています。 jpgファイルが作成されることはされるのですが、中身をみることができない状態になってしまいます。 どこが悪いのかわかる方がおられましたらご教授お願いします。 <ソースコード> #include <windows.h> #include <stdio.h> #include <wininet.h> int main(void) { HINTERNET hInet, hUrl; char szBuf[128], szUrl[128], *lpszSrc; DWORD dwRead, dwTotal = 0; HGLOBAL hMem; FILE *file; printf("URL---- "); gets(szUrl); hInet = InternetOpen(TEXT("neko"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(hInet == NULL){ perror("オープンエラー\n"); return -2; } hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0); if(hUrl == NULL){ perror("URLオープンエラー\n"); return -3; } hMem = GlobalAlloc(GHND, 1); lpszSrc = (char*)GlobalLock(hMem); while(1){ InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf)-1, &dwRead); szBuf[dwRead] = '\0'; if(dwRead == 0){ break; } dwTotal += dwRead; hMem = GlobalReAlloc(hMem, dwTotal+1, GMEM_MOVEABLE); lpszSrc = (char*)GlobalLock(hMem); strcat(lpszSrc, szBuf); } if((file = fopen("test.jpg", "wb")) == NULL){ printf("ファイルオープンエラー\n"); goto end; } while(dwTotal){ fputc(*lpszSrc, file); lpszSrc++; dwTotal--; } fclose(file); end: GlobalUnlock(hMem); GlobalFree(hMem); InternetCloseHandle(hUrl); InternetCloseHandle(hInet); return 0; } <環境> Windows Vista VC++ 2005 EE

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

文字列を扱っているわけではないので, ・szBuf[dwRead] = '\0'; は不要ですし, ・strcat(lpszSrc, szBuf); はmemcpyを使う必要があります。 特に,後者は0x00が出てきた時にデータが壊れる原因になっています。

kerokk
質問者

お礼

迅速なご回答ありがとうございます。 無事問題を解決することができました! 適切なご指摘、とても助かりました。

関連するQ&A

  • InternetOpenUrlについて

    InternetOpenUrlを同一プログラム内で繰り返し使おうと思っているのですがうまくいきません ちなみにソースは hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { perror("オープンエラー\n"); return -2; } //HTTPセッションの開始, 指定のURLオープン hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0); if (hUrl == NULL) { perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } GetHtml(hInet,hUrl); pNext=GetMeigara(); printf("%s\n",pNext); remove("html.txt"); //インターネットハンドルの解放 InternetCloseHandle(hUrl); InternetCloseHandle(hInet); while(pNext != NULL){ hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { perror("オープンエラー\n"); return -2; } hUrl = InternetOpenUrl(hInet, pNext, NULL, 0, 0, 0); if (hUrl == NULL) { perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } GetHtml(hInet,hUrl); pNext=GetMeigara(); remove("html.txt"); InternetCloseHandle(hUrl); InternetCloseHandle(hInet); if(pNext==NULL) break; } 見づらくて申し訳ありません ちなみにループの中のInternetOpenUrlでオープンエラーになります

  • htmlソースを一文字ずつ取得するには・・

    私は猫でもわかるネットワークプログラミングをよんでふと思ったのですが・ HTMLソースを空白行も含め縦に並べたいのです たとえば・・ < h t m l > ってな感じで・・ つまりは printf("%s(%cでも・・)",一文字); ってな感じにしたいのです・・ 一応作りかけのソース張っておきます。。。。 wininet使ってます・・ //省略 //インターネット(wininet)開始 hInet = InternetOpen("ユーザー名収集プロトタイプ",INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0); hUrl = InternetOpenUrl(hInet,szUrl,NULL,0,0,0); //lpszSrcに1バイトのみ確保 hMem = GlobalAlloc(GHND,1); lpszSrc = (char *)GlobalLock(hMem); //読み出すものがなくなるまで読み出す while(1){ InternetReadFile( hUrl,szBuf,(DWORD)sizeof(szBuf) - 1,&dwRead); szBuf[dwRead] = '\0'; //読み出すものが無くなったらループを脱出 if (dwRead == 0){ break; } //必要バイト数の計算 dwTotal += dwRead; //確保領域の大きさ変更 hMem = GlobalReAlloc(hMem,dwTotal,GMEM_MOVEABLE); if(hMem == NULL){ perror("再アロケート失敗\n"); } lpszSrc = (char *)GlobalLock(hMem); if(lpszSrc == NULL){ perror("メモリ領域確保に失敗\n"); break; } strcat(lpszSrc,szBuf); printf("%s\n",szBuf); } //メモリの開放 GlobalUnlock(hMem); GlobalFree(hMem); //インターネットハンドルの開放 InternetCloseHandle(hUrl); InternetCloseHandle(hInet); return 0; }

  • InternetOpengaが使えません・・・。

    すみません。 どーしてもできません。教えてください。 下記のプログラムを走らせたいのですが、エラーが直りません。 開発環境はVC++2008です。 プロジェクト新規でwin32コンソールアプリケーションを選択し、 空のプロジェクトを作成したあと、 WinInet.Libを追加しています。 下記のプログラムで、下記のようなエラーがでます。。。、 ------ ビルド開始: プロジェクト: readhtml, 構成: Debug Win32 ------ コンパイルしています... readhtml.cpp warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(279) : 'gets' の宣言を確認してください。 error C2664: 'InternetOpenW' : 1 番目の引数を 'const char [16]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 error C2664: 'InternetOpenUrlW' : 2 番目の引数を 'char [128]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 readhtml - エラー 2、警告 1 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== ある本を見ながら、作成し、サンプルどおりに作っているのですが・・。 #include <windows.h> #include <stdio.h> #include <wininet.h> int main() { HINTERNET hInet,hUrl; char szBuf[128],szUrl[128],*lpszSrc; DWORD dwRead,dwTotal = 0; HGLOBAL hMem; //目的のURLの入力 printf("URL---"); gets(szUrl); //インターネット(WinInet)の開始 hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0); if (hInet == NULL){ perror("オープンエラー\n"); return -2; } //HTTPセッションの開始、指定のURLオープン hUrl = InternetOpenUrl(hInet,szUrl,NULL,0,0,0); if (hUrl == NULL){ perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } //lpszSrcに1バイトのみ確保 hMem = GlobalAlloc(GHND,1); lpszSrc = (char *)GlobalLock(hMem); //読み出すものがなくなるまで読み出す while(1){ InternetReadFile( hUrl, szBuf, (DWORD)sizeof(szBuf) - 1 , &dwRead); szBuf[dwRead] = '\0'; //読み出すものがなくなたのでループ脱出 if (dwRead == 0){ break; } //必要バイト数の計算 dwTotal += dwRead; //確保領域の大きさ変更 hMem = GlobalReAlloc(hMem, dwTotal + 1, GMEM_MOVEABLE); if (hMem == NULL){ perror("再アロケート失敗\n"); } lpszSrc = (char *)GlobalLock(hMem); if (lpszSrc == NULL) { perror("メモリ確保に失敗\n"); break; } strcat(lpszSrc,szBuf); } //ソースの表示 printf("%s\n",lpszSrc); //メモリの開放 GlobalUnlock(hMem); GlobalFree(hMem); //インターネットハンドルの開放 InternetCloseHandle(hUrl); InternetCloseHandle(hInet); return 0 ; }

  • CGIと通信するプログラムを作っています。

    #include<windows.h> #include<stdio.h> #include<wininet.h> int main(){ HINTERNET hInet,hUrl; char szBuf[128],szUrl[128],*lpszSrc; DWORD dwRead,dwTotal=0; HGLOBAL hMem; printf("URL:"); gets(szUrl);      ~~~~        略      ~~~~ こんな風にアドレスを入力して接続するプログラムを作っているのですが GETの時はそのまま,「www.○○.com/○○.cgi?=aiueo」こんな風に入力するだけで通信が出来たのですが、POSTのCGIと通信する方法がよくわかりません。 どなたか教えてください。よろしくお願いします。

  • wininetでPOSTで値を渡せません

    winnetを使ってPOST形式でサーバにパラメータを渡そうとしていますが、パラメータが渡せずに困っています。 HttpOpenRequestかHttpSendRequestがおかしいと思うのですが、自分では見当がつきません。 よければ何処に問題があるのか教えてください。 環境:vc++2005 int DoHttpRequest( void ) { HINTERNET hInet, hSession, hRequest; DWORD dwTotal = 0; wchar_t param[] = L"type=1"; wchar_t header[] = L"Content-Type: application/x-www-form-urlencoded"; wchar_t accept[] = L"Accept: */*"; // 使ってない BOOL flag; Console::WriteLine( "Http接続START" ); //インターネット(WinInet)初期化 hInet = InternetOpen( NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { Console::WriteLine( "エラー1" ); return -1; } // サーバへ接続 hSession = InternetConnect( hInet, L"192.168.11.25", 9999, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ); if( hSession == NULL ) { Console::WriteLine( "エラー2" ); InternetCloseHandle(hInet); return -1; } //HTTPセッションの開始, 指定のURLオープン hRequest = HttpOpenRequest( hSession, L"POST", L"/sample/service.php", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0 ); if (hRequest == NULL) { Console::WriteLine( "エラー3" ); InternetCloseHandle(hSession); InternetCloseHandle(hInet); return -1; } // 送信 flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param )); if( flag == FALSE ) { Console::WriteLine( "エラー4" ); InternetCloseHandle(hRequest); InternetCloseHandle(hSession); InternetCloseHandle(hInet); return -1; } //インターネットハンドルの解放 InternetCloseHandle( hRequest ); InternetCloseHandle( hSession ); InternetCloseHandle( hInet ); Console::WriteLine( "Http接続END" ); return 0; }

  • VC++ HttpOpenRequest() 正しく終了しない。

    MFC-dllを作成してVBで使用しようと思っています。 DLLの中ではWebサーバーに接続してデータを取得して VBで使う感じです。 DLLの中でダイアログボックスを一個作ってその中で実際のサーバーとの通信を行います。次のコードはそのDLL中のダイアログボックスの中でボタンを押したとき実行される関数です。 動きとしてはサーバーに接続し、データを正しく取得できますが、問題はこのDLLを使っているVBプログラムが終了してもWindows タスクマネージャーを見ると終了されてない状態です(デスクトップ画面上では終了されています)。しばらくしたら『応答なし』になって結局2~3分たったら自動に消滅されるのですが何だか感じ悪いです。コードの中に何か問題があるかどうか教えてください。 Void CTest::GetA (){ CHAR buffer[2048]; DWORD dwRead; char Header[]="Content-Type: application/x-www-form-urlencoded\n"; char Data[]="name=JohnDoe"; HINTERNET hINet=InternetOpen("V1.0",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); HINTERNET hCon=InternetConnect(hINet,"localhost",8080,"","", INTERNET_SERVICE_HTTP,0,0); HINTERNET hData = HttpOpenRequest(hConnection,"POST","/test001.asp",NULL,NULL,NULL,INTERNET_FLAG_KEEP_CONNECTION,0); HttpSendRequest( hData, Header, strlen(Header),Data,strlen(Data)); while( InternetReadFile( hData, buffer, 255, &dwRead ) ) { if ( dwRead == 0 ) break; buffer[dwRead] = 0; m_strContents += buffer; } InternetCloseHandle(hCon); InternetCloseHandle(hINet); InternetCloseHandle(hData); }

  • C言語 iMacでのファイル入出力

    #include <stdio.h> int main() { FILE *fp; fp=fopen("test.txt","w"); if (fp==NULL){ perror("ファイル・オープンに失敗しました\n"); return -1; }else printf("ファイルを正常に開きました\n"); fprintf(fp,"これが初めてのファイル入出力です\n"); if (fclose(fp)!=0){ perror("ファイル・クローズに失敗しました\n"); return -1; }else printf("ファイルを正常に閉じました\n"); return 0; } これを実行してもどこにもtest.txtというファイルがありません。 同じプログラムをwinでも実行してみたところ正常にファイルが作られました。 mac初心者なもんで、どうすればいいのでしょうか?

  • 【C&C++】文字コードEUCをShift-JISに変換したい

    WinInetで指定したURLのHTMLを表示するコンソールプログラムを作成したのですが、EUCで書かれたWebページが文字化けをしてしまいます。 Shift-JISで書かれているWebページは特に問題なく、自分もEUCからShift-JISに変換したいと考えています。しかし、色々と参考書やWebなどを調べてみたのですが、自分には少し難しすぎてより分かりやすい説明を求めています。 データの読み出しはInternetReadFileを使用しています。以下がそのソースです。 while (1) { InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf) - 1, &dwRead); szBuf[dwRead] = '\0'; if (dwRead == 0) break; str = str + szBuf; } どうかご回答よろしくお願いします。

  • 【C&C++】EUC_JPをSHIFT-JISに変換したい

    WinInetで指定したURLのHTMLを表示するコンソールプログラムを作成したのですが、EUC_JPで書かれたWebページが文字化けをしてしまいます。 SHIFT-JISで書かれているWebページは特に問題なく、自分もEUC_JPからSHIFT-JISに変換したいと考えています。しかし、色々と参考書やWebなどを調べてみたのですが、自分には少し難しすぎてより分かりやすい説明を求めています。 データの読み出しはInternetReadFileを使用しています。以下がそのソースです。 while (1) { InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf) - 1, &dwRead); szBuf[dwRead] = '\0'; if (dwRead == 0) break; str = str + szBuf; } どうかご回答よろしくお願いします。

  • テキストファイルの文字列の削除

    1行あたりIPアドレスが1つ書いてあるテキストファイルから、指定したIPアドレスを削除するプログラムを作成しています。 r+モードでfoepnした後にfgetsで一行ずつ読み取り、指定されたIPアドレスかどうかをチェックし、該当すればその行をNULLで埋め尽くしているのですが、サクラエディタなどで開くとその行が削除ではなくNULL文字で埋め尽くされているといった現象になります。 削除するにはどうすればよいでしょうか? ipaddress.txt --------------------- 192.168.0.1(\n) 192.168.0.2(\n) 192.168.0.3(\n) --------------------- 以下、コード bool DeleteAllowIP(char *ipaddr) {   FILE *fp;   char szBuf[256];   int leng = 0;   long posi=0;   // 初期化   FillMemory(szBuf, sizeof(szBuf), 0);   // ファイルオープン(追記)   if(fopen_s(&fp, AllowPath, "r+"))     return FALSE;   // 削除   while (NULL != fgets(szBuf, sizeof(szBuf), fp)){  // 1行読み取る     if(NULL != (strstr(szBuf, ipaddr))){  // 削除IPに合致するIPを検索       fseek(fp, posi+1, SEEK_SET);  // 削除する先頭行セット       leng = strlen(szBuf) - 1;  // 改行を除く文字数を取得       while(leng>=0){   // 文字数分'\0'をセット         fseek(fp, posi+leng-1, SEEK_SET);         leng--;         fputc('\0', fp);       }       fseek(fp, posi+1, SEEK_SET);  // 次の行の先頭にセット     }     posi = ftell(fp);   }   // ファイルクローズ   fclose(fp);   return TRUE; }