- 締切済み
InternetReadFile関数でHTMLデータをメモリに格納
BLUEPIXYの回答
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#1>http://www.yahoo.co.jpのHTMLソースを取得する場合 InternetOpenUrlで、 "http://www.yahoo.co.jp" を指定したら、取得できます。 大抵のWEBサーバーでは、デフォルトでindex.htmlになっているので、 "http://www.yahoo.co.jp/index.html" でいいですが、 "http://www.yahoo.co.jp" を指定しても、 "http://www.yahoo.co.jp/index.html" を返してくれます。 (実際試してみました)
関連するQ&A
- InternetReadFileを使ったファイルダウンロード
下のようなプログラムは、httpサーバから特定のファイルを ダウンロードすることが目的です。 (※referer, file名は仮のものです。) 試しに動かしてみて、転送速度が比較的速い場合には、一応問題なく ダウンロードすることができたのですが、転送速度が遅い場合には、 ファイルサイズがどんどん膨れ上がってしまいます。 問題は、InternetReadFileでブロックされることがないからだと 推測しましたが、情報が少なく困っています。 転送速度が遅い場合にも正常にダウンロードするにはどうしたら よいでしょうか? #include <windows.h> #include <wininet.h> #include <stdio.h> #include <stdlib.h> bool GetHttpFile(){ HINTERNET hInternet; HINTERNET hFile; char Buf[1000]; /* バッファ */ DWORD ReadSize; BOOL bResult; wchar_t szHead[] = TEXT("Referer:http://aaa.com/\r\n\r\n"); // ヘッダにRefererを追加する FILE *fp; bool ret; /* 保存先ファイル作成/open */ fp = fopen("sample.zip", "wb"); if (fp == NULL){ /* ファイル作成/openに失敗 */ ret = false; }else{ /* ファイル作成/openに成功 */ /* WININET初期化 */ hInternet = InternetOpen( TEXT("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); /* URLのオープン */ hFile = InternetOpenUrl( hInternet, TEXT("http://aaa.com/bbb.zip"), szHead, 0, INTERNET_FLAG_RELOAD, 0); /* オープンしたURLからデータを(1000バイトずつ)読み込む */ for(;;){ ReadSize = 1000; bResult = InternetReadFile( hFile, Buf, 1000, &ReadSize); /* 全て読み込んだらループを抜ける */ if(bResult && (ReadSize == 0)) break; /* ファイルに書き込み */ fwrite(Buf, sizeof(char), 1000, fp); } /* 後処理 */ InternetCloseHandle(hFile); InternetCloseHandle(hInternet); fclose(fp); ret = true; } return ret; } int main(){ if(GetHttpFile() == true){ printf("成功\n"); }else{ printf("失敗\n"); } return 0; }
- ベストアンサー
- C・C++・C#
- C言語 ファイル内のデータと入力したデータの重複
テキストファイルを読み込み、入力したデータとの重複がないかどうかを調べたいのですが、 わからない点があるため、質問させていただきます。 -------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char datafile[];= "sample.txt"; char buff[512]; //読み込んだ1行分のデータを格納 char *data[1000]; //読み込んだデータを格納 int data_c = 0; //データの数 char str[256]; //入力された文字列を格納 int i; int check; //重複チェック (中略) //ファイルを1行ずつ読み込み、その長さのメモリを確保し、値をコピー while(fgets(buff, sizeof buff, fp) != NULL) { data[data_c] = (char*)malloc(strlen(buff) + 1); strcpy(data[data_c++], buff); } (中略) //文字列を入力 fgets(str, 256, stdin); check = 0; //すでにあるデータと入力したデータの重複を調べる for(i=0; i<data_c; i++) { if(strcmp(data[i], str) == 0) { check = 1; break; } } (中略) -------------------------------------------------------- 例えば読み込むファイルに5行書かれていた場合、 data[0]からdata[4]に確保したメモリの先頭アドレスが格納されますよね? ということはdata_cの値は4となるのですが、 その後のファイルデータと入力したデータの重複を調べるところで、 for(i=0; i<data_c; i++) となっており、data[0]からdata[3]までの4行分しか調べられないことになります。 なぜ、i<=data_cではなく、i<data_cとなっているのか、わかりましたら教えていただけますでしょうか。
- 締切済み
- C・C++・C#
- ある関数のソースがわかりません。
KOKUGO=100 SUUGAKU=80 RIKA=0 SYAKAI=60 というファイルを取得して数字だけ構造体に渡す関数のソースです。 define KOKUGO 3; define SUUGAKU 2; define RIKA 1; define SYAKAI 2; 構造体は typedef struct{ char koku[KOKUGO +1]; char suu[SUUGAKU +1]; char rika[RIKA + 1]; char sya[SYAKAI + 1]; }data; です。 全体ではデータを読み取ってcsv形式で出力するプログラムなんですが main関数、出力関数はちょっと省きます。 int Readfile(data *txtfile, char *ptxt) { FILE *fp; char *fullcode = NULL; char search = '='; char buff[30] = {'\0'}; int enum[4] = {'\0'}; int err = 0; char *rtxt = NULL; /*ファイルオープン*/ fp = fopen(ptxt, "r"); if(fp == NULL){ puts("オープンエラー"); return(1); } /*ファイル読み取り*/ while(1){ /*データを一行ずつ読み取り*/ rtxt = fgets(buff, sizeof(buff), fp); if(rtxt == NULL){ break; } /*データ名確認*/ if(strncmp(buff, "KOKUGO=", 7) == 0){ ••••••••••• (1) /*'='を含むデータ確認*/ fullcode = strchr(buff, search); /*'='より後ろの点数確認*/ fullcode += 1; /*点数桁数確認*/ if(strlen(fullcode) == KOKUGO + 1){ /*構造体に点数のみ格納*/ strncpy(txtstr -> koku, fullcode, KOKUGO); enum[0] += 1; }else{ puts("データが違います") return(1); } }else if(strncmp(buff, "SUUGAKU=", 8) == 0){ fullcode = strchr(buff, search); fullcode += 1; if(strlen(fullcode) == SUUGAKU + 1){ strncpy(txtstr -> suu, fullcode, SUUGAKU); enum[1] += 1; }else{ puts("データが違います") return(1); } } else if(strncmp(buff, "RIKA=", 5) == 0){ fullcode = strchr(buff, search); fullcode += 1; if(strlen(fullcode) == RIKA + 1){ strncpy(txtstr -> rika, fullcode, RIKA); enum[2] += 1; }else{ puts("データが違います") return(1); } } else if(strncmp(buff, "SYAKAI=", 7) == 0){ fullcode = strchr(buff, search); fullcode += 1; if(strlen(fullcode) == SYAKAI + 1){ strncpy(txtstr -> sya, fullcode, SYAKAI); enum[3] += 1; }else{ puts("データが違います") return(1); } } } for(err = 0; err < 4; err ++){ if(enum[err] != 1){ puts("データが違います"); return(1); } } /*ファイルを閉じる*/ fclose(fp); return(0); } という風に書いてあるんですが(1)の部分で7文字比較して等しければ 次の/*'='を含むデータ確認*/に進むと思うんですが等しくなければ どういう処理が行われ、どこに進むのかわかりません。 基本的にこの無限ループの流れがわかりません。 このソースの読み方を教えてください。 友達が以前書いたソースなんですが聞いてももうわからないらしくて・・・。 すいませんが、勉強し始めたばかりなので詳しくお願いします。
- ベストアンサー
- C・C++・C#
- WinInetのInternetOpenUrl関数が正常に動作しない。
ネットワーク上のHTMLソースを取得しようとしています。InternetOpenUrl関数が動作せず、常にNULLが返ってきます。 環境は、WindowsXP、WindowsCE Platform Builder です。 void Get_HTML(){ HINTERNET hInternet; HINTERNET hFile; char Buff[1000]; DWORD ReadSize; BOOL bResult; //WinInetの初期化 char *agent ="WININET Sample Program"; hInternet = InternetOpen( (LPCWSTR)agent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); if( hInternet == NULL ){ printf("InternetOpen Error \n"); } //ネット接続チェック if( InternetAttemptConnect(0) != ERROR_SUCCESS { printf("インターネットに接続できません。\n"); } else{ printf("インターネットに接続できる\n"); } //URLオープン char open_url="http://www.sample.com/sam1.html"; hFile = InternetOpenUrl( hInternet, (LPCWSTR)open_url, NULL, 0, INTERNET_FLAG_RELOAD, 0 ); printf("%s",(LPCWSTR)open_url); if( hFile == NULL ){ printf(" InternetOpenUrl ERROR \n"); } } InternetOpenUrl関数の戻り値がNULLになりReadを することが出来ません。 解決方法よろしくお願い致します。
- ベストアンサー
- C・C++・C#
- ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込
ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込みプログラム」をそのままコンパイルして実行しようと思ったのですが、 sample.c: In function 'main': sample2.c:9: warning: return type of 'main' is not 'int' と、表示されてしまいます。 プログラミング初心者なので、どこが間違っているのかわかりません。 回答またはアドバイスの程、よろしくお願いいたします。 ネットで落ちていたプログラムを以下に記載します。 sample2.c #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("コマンドの入力形式が間違っています.\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("ファイルがオープンできません[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("データが不正です[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("エラー(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("エラー(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("エラー(3)\n"); break; } if(*wp != '\0'){ printf("エラー(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); }
- ベストアンサー
- C・C++・C#
- データの読み込みがうまくいかなくて、困っています
プログラミング初心者です。 誤差逆伝播学習のプログラムを行っています。 C言語で、データの読み込み部分がうまくいかなくて、困っています。 borland , BCC Developerなどを用いてやっております。 やりたいことは、テキストファイルから数字を読み込み、それを行列に格納してデータとして送るということです。 その際に、テキストファイルで行と列で表示されたものを送ろうと考えています。30×30の、1と0で表示された絵と教師信号を読み取っています。 列だけの読み込みは正常に動いたのですが、行と列で表示されたものの読み込みができません。char型で変数を宣言しているので、数字として読み込めていないとか、そういったことがあるのでしょうか。o1[][],t[][]の部分に正しく値が送れるようにしたいです。 非常にわかりにくくて申し訳ないのですが、お分かりになる方がいたら、どこをどう変えれば良いか、教えて頂きたいです。 「間違っている列と行の読み込み」 //データをファイルから読み込む// void read_file(name) char *name; { int i,j,k; //ループカウンター// FILE *fp; //ファイルポインタ// char buff[MCHS]; //buffの最大文字数1024 //ファイルオープン// if((fp=fopen(name,"r"))==NULL){ fprintf(stderr,"%s:File open error !!\n",name); exit(-1); } //学習データを読み込む// fscanf(fp, "%d",&learning_pattern_no); //学習パターンの数読み込み fscanf(fp,"%d",&test_pattern_no); //テストパターンの数読み込み printf("学習パターンの数:%d\n",learning_pattern_no); //学習パターンの数表示 printf("テストパターンの数:%d\n",test_pattern_no); //テストパターンの数表示 i=0;j=0; while( fgets( buff, MCHS, fp ) != NULL ){ if(j<=learning_pattern_no+test_pattern_no-1){ for( k=0; k<MCHS; k++ ){ o1[j][i+k]=buff[k]; //o1[j][i+k]にbuff[k]を入れる printf("%c",buff[k]); //printfで確認 if( buff[k] =='\n'){ i=i+k; if (i==InputUnitNo){ i=0; j++; printf("%d",j); }//if(i==InputUnitNo)終了 break; }//if(buff[k])終了 }//for終了 }//if(j<=learn+test)終了 else{ //ここから教師信号の読み取り for( k=0; k<MCHS; k++ ){ t[i][k]=buff[k]; printf("%c",buff[k]); //教師信号の確認 if( buff[k] == '\n' ){ i++; break; }//if(buff[k])終了 }//for終了 }//else終了 }//while終了 } 「正常に動いた列だけの読み込み」 //データをファイルから読み込む// void read_file(name) char *name; { int i,j; //ループカウンター// FILE *fp; //ファイルポインタ// //ファイルオープン// if((fp=fopen(name,"r"))==NULL){ fprintf(stderr,"%s:File open error !!\n",name); exit(-1); } //学習データを読み込む// fscanf(fp, "%d",&learning_pattern_no); printf("学習データの数:%d\n",learning_pattern_no); for(i=0;i<learning_pattern_no; i++){ for(j=0;j<InputUnitNo; j++) fscanf(fp,"%lf",&o1[i][j]); for(j=0;j<OutputUnitNo; j++) fscanf(fp,"%lf",&t[i][j]); //教師信号 } //テストデータを読み込む// fscanf(fp,"%d",&test_pattern_no); printf("テストデータの数:%d\n",test_pattern_no); for(i=learning_pattern_no;i<learning_pattern_no+test_pattern_no;i++) for(j=0;j<InputUnitNo;j++) fscanf(fp,"%lf",&o1[i][j]); fclose(fp); }
- 締切済み
- C・C++・C#
- ファイルから構造体へデータを格納(動的メモリ割り当て)
C言語の勉強をしいております。 typedef struct address { char names[32]; /* 名前 */ char tels[32]; /* 電話番号 */ struct address *prev; /* 前のリスト */ struct address *next; /* 次のリスト */ }Address; という構造体へ、ファイルから読み込んだテキストデータ(名前と電話番号がTABで区切られている)を格納したいのですが、配列ではなく、動的にメモリを確保しながら格納する方法を教えていただけないでしょうか? 処理の流れとしては、 ・1つめの構造体の*prevにはnullを入れておく。 ・1つめの構造体へファイルの1件目のデータを格納する。 ・ファイルのデータがまだある場合には、malloc関数を使ってメモリを確保し、malloc関数からの戻り値を1つめの構造体の*nextへ格納する。 ・構造体へ2件目のデータを格納する。 このような感じだろうという程度しか分からず、ソースも書けずにいます・・・。 配列を使用したサンプルはあるんですが、動的に処理を行う方法を教えていただけないでしょうか? よろしくお願いいたします。
- 締切済み
- C・C++・C#
- ConvertINetStringについて
wininetのInternetReadFileでUTF-8のサイトから文字列を受け取ったところ、2バイト文字が文字化けしていました。 ConvertINetStringでUTF-8からShift_JISに変換しようとしていますが上手くいかず困っています。 プログラムは下のようになっています。 DWORD mode = 0, readSize; char src[1024]; BYTE dst[1024]; int srcLen, dstLen; char c[1024]; while( true ) { readSize = 0; ::ZeroMemory(src, sizeof(src)); ::ZeroMemory(dst, sizeof(dst)); // 受信 InternetReadFile( hRequest, src, sizeof(src), &readSize ); if(readSize == 0) break; srcLen = strlen(src); dstLen = sizeof(dst) - 1; // UTF-8からShift_JISへ ConvertINetString(&mode, 65001, 932, src, &srcLen, dst, &dstLen); // BYTEからcharへ for(int i = 0; i < strlen(dst); i++) c[i] = (char)dst[i]; Console::WriteLine("受信:{0}", gcnew String(dst)); } 1.ConvertINetStringでdstに値がちゃんと入らない(「・」みたいなゴミのような文字が入ります) 2.本題とは逸れるのですが、BYTEからcharへの変換はこれでいいのでしょうか? ConvertINetStringが上手くいかない理由が特にわからないので回答をもらえたらありがたいです。
- ベストアンサー
- C・C++・C#
- 文章中から特定の文字列を抜き出すプログラムについて C言語
log.txtの文章からIPを抜き出しip.txtに書き込むというものです。log.txtの文章は基本的にfrom IP:port の順です。しかし文章中にfromがないとip.txtで空欄になってしまいます。 例192.168.1.100 192.168.1.110 理想はfromがない行はなにも追加せず次に移りたいのですがどうすればいいでしょうか? 例192.168.1.120 192.168.1.130 192.168.1.140 void addLine(const char*,FILE*); char *getFromIP(const char*,char*); int main() { FILE *pFileA = fopen("log.txt","rt"); char buff[256]; if(pFileA){ FILE *pFileB = fopen("ip.txt","wt"); if(pFileB){ for(;fgets(buff,256,pFileA) != NULL;){ char buff2[32] = {'\0'}; addLine(getFromIP(buff,buff2),pFileB); } fclose(pFileB); } fclose(pFileA); } return 0; } char *getFromIP(const char *line, char *buff) { char *src, *dst; src = strstr(line, "from"); if(src==NULL) { return buff; } src += 4; dst = buff; while(1) { if(isspace(*src)) { src++; continue; } else break; } while(1) { *dst = *src; if(*dst == ':') { *dst = '\0'; break; } if(*dst == '\0') { break; } dst++; src++; } return buff; } void addLine(const char *str,FILE *pFile){ char buff[1024]; sprintf(buff,"%s\n",str); fputs(buff,pFile); }
- ベストアンサー
- C・C++・C#
- メモリ
#include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> int check(int a[100], int n); typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test3.csv","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } int p, q; int a[100]; int u = 0; for(p = 0; p < line; p++){ for(q = 0; q < line; q++){ if(strcmp(data[p].class_type, data[q].class_type) == 0 && strcmp(data[p].subject, data[q].subject) == 0 && p != q ){ //処理 } } } } fclose(fp); return 0; } 先日文字列入れ替えについてご質問したものですが メモリの取り方についてご質問します。 先日このプログラムにおいて my data[100]と固定してるのはいけないという意見をもらったので メモリを取得しようと思ってるのですが できればdata[i].○○の形でアクセスしたいのでこのままの形は あまりかえたくないです。この場合 while(fgets(buf,1000,fp) !=NULL){ str=buf; int len = strlen(buf); my *o; o = (my *)calloc( len + 1, sizeof(my *)) while(*str != '\0'){ としてみたのですがこれは実際どうなのでしょうか? NULLは帰ってきてないみたいなので割り当ては出来てるとは思うんですが この一行の文字列の大きさにぴったり合うメモリを割り当てたいのですが ちゃんとなっているか調べる方法を教えて下さい。
- ベストアンサー
- C・C++・C#
補足
もし、index.htmlで得られないWebサーバーでは、 HttpOpenRequest()→HttpQueryInfo()の流れはできないのでしょうか? GYAOのページでは、http://www.gyao.jp/にindex.htmlを付加したらエラーになります。