スクリーンセーバーを作ろう!
(3)htmlを解析する機能
前章で、"http://homepage1.nifty.com/mou-usshisshi/sub3.htm"
ローカルファイルダウンロードしたので、今度はタグ解析します。
ポイント<img>タグを探すのみです。
だって、このプログラムは画像をダウンロードするのが目的なので。
方法はローカルファイルOPENして
1行ずつ読み込み文字列検索をします。

とりあえず、プログラムを見てみましょう!
mouget.cppの一部
int
GetImgList()
{
    FILE    *fp ;
    char    buff[1024] ;

    // ダウンロードしてくる
    if ( MakeWorkFile() == 0 ) {
        DeleteFile( WorkFile ) ;
        return( 0 ) ;
    }

    // ファイルのOPEN
    fp = fopen( WorkFile, "r" ) ;
    if ( fp == NULL ) {
        DeleteFile( WorkFile ) ;
        return( 0 ) ;
    }

    ImgCnt = 0 ;

    // ファイルの終りまでループ
    while( !feof( fp ) ) {
        char *pw, *pw1 ;
        char *pImg ;


        // ファイルから1行ずつ読み込む
        if ( fgets( buff, sizeof(buff) ,fp ) == NULL ) break ;

        // 文字列 "IMG" または "img" を探す
        if ( (pw = strstr( buff, "IMG" )) == NULL ) {
            if ( (pw = strstr( buff, "img" )) == NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
            }
        }

        // 文字列 "SRC" または "src" を探す
        pw1 = pw ;
        if ( (pw = strstr( pw1, "SRC" )) == NULL ) {
            if ( (pw = strstr( pw1, "src" )) == NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
            }
        }

        // 文字列 "=" を探す
        pw1 = pw ;
        if ( (pw = strstr( pw1, "=" )) == NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
        }

        // 文字列 " を探す
        pw1 = pw ;
        if ( (pw = strstr( pw1, "\"" )) == NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
        }

        pw ++ ;
        pImg = pw ;

        // 文字列 " を探す
        pw1 = pw ;
        if ( (pw = strstr( pw1, "\"" )) == NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
        }
        *pw = NULL ;

        // "mou-Logo"を探す
        if ( strstr( pImg, "mou-Logo" ) != NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
        }
        // "banner"を探す
        if ( strstr( pImg, "banner" ) != NULL ) {
                memset( buff, 0, sizeof( buff ) ) ;
                // ないのでループを続ける
                continue ;
        }

        // 画像ファイルをストア
        sprintf( ImgFile[ImgCnt], "%s", pImg ) ;
        ImgCnt ++ ;
        if ( ImgCnt == 10 ) break ;
    }
    fclose(fp) ;
    DeleteFile( WorkFile ) ;


    return( 1 ) ;

}
ベタなプログラムでスンマセン。m(_ _)m
コンパクトにまとめようと思えば出来なくもなさそうだけど
とりあえずこれでいいっしょ?(^^;;;

fgets( buff, sizeof(buff) ,fp ) ;
で1行を読み込んできます。
例えば
<A href="n-usi1.htm"><IMG src="usi592.gif"></A>
という読み込みます。
buffの領域↓こんな感じなります。
<A_href="n-usi1.htm"><IMG_src="usi592.gif"></A>\0


で、buffの中から
"IMG" という文字列を探します。
strstr()を使います。文字列から文字列検索する関数です。
pw = strstr( buff, "IMG" ) ;
を実行すると
<A_href="n-usi1.htm"><IMG_src="usi592.gif"></A>\0
pw"IMG"先頭のアドレスを得ます。上のピンク色の位置。


次に
"src" という文字列を探します。
pw = strstr( pw1, "src" ) ;
あ、pw1ってのは前の行で pw1 = pw としているのでつまるところ "IMG" の "I" の位置を示します。
で実行すると
IMG_src="usi592.gif"></A>\0
pwは "src" の先頭のアドレスを得ます。上のピンク色の位置。
同様に "=" を探します。
pw = strstr( pw1, "=" ) ;
src="usi592.gif"></A>\0

 "(ダブルコーテション)マーク を探します。
pw = strstr( pw1, "\"" ) ;
「\"」と表現しているのは「"」で囲った時の「"」を示しています。
こうやらないと、コンパイルエラーになります。

="usi592.gif"></A>\0
ここでやっと画像ファイル名先頭位置わかりました
"usi592.gif"></A>\0
つまりこの時点で pw が指しているアドレス一つ後ろ
ファイル名の先頭となります。
上のピンク色の位置ですね。


で、ここで思ったんだけど、ファイル名の先頭にスペースとかタブがあったら無視すべきだよねぇ〜(^^;;;
さて、同じような説明が続いてますが
さらにファイル名のお尻を同様に求めていきます
閉じの " マークを探します。
pw = strstr( pw1, "\"" ) ;
usi592.gif"></A>\0
そこに NULLをぶち込んで文字列を切ります。
NULL とは '\0' 0x00 10進数でいえば 0 まぁ表現はなんでもいいのですが。
文字列の区切り意味します
usi592.gif\0
って感じで、ファイル名の切り出し成功しました。
もっとスマートに作れそうな気もしますが・・・スンマセン・・・m(_ _)m
尚、"mou-Logo" とか "banner" を検索しているのは
それぞれ、タイトル文字、バナーなのでスクリーンセーバーには不要なので無視しています。(^^;;;

ってことで、一連の処理ループをして
htmlファイル内検索してファイル名拾っていきます
あ、あと、いままで説明してきた手順の中で文字列が見つからなかった場合は
その行は不要と判断して次の行の処理へと移行します。

ああ、マヌケなロジック・・・(!¬¬)

←前へ →次へ