ファイルの書き込みでなぜか違うデータが書き込まれる

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

ファイルの書き込みでなぜか違うデータが書き込まれる

#1

投稿記事 by shiro4ao » 13年前

こんにちはshiro4aoです。

試しにhttpレスポンスからhtmlボディを取り出すソフトを書いてみようと思いました。
かなり胡散臭い方法で切りだそうとしているのですが、
方法が稚拙という点以外に問題が出ました。

下記コードの書き込み用バッファoutputに書きこまれた内容と
fwrite()で出力したファイルの中身が違うのです。
「データの先頭や末尾がなくなった」という状態ではなく、
「頻繁に欠けている部分が発生する」という状態でお手上げになってしまいました。

何か解決方法はありますでしょうか。

コード:

#include <stdio.h>
#include <openssl/rc4.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

int SplitContent(char *in)
{
	FILE *fp,*fp2;
	char *data; 
	char *output;  
	size_t size;      
	int bufsize;
	int Count;
	char Cbuf[100];
	char *p,*p2,*p3;
	int ContentLength;
	
	Count=0;

	data=(char*)malloc(sizeof(char)*10);
	bufsize=10;
	size=bufsize;

	while(1){
		fp = fopen(in, "rb" ); 
		if( fp == NULL )
		{
			printf( "%sが開けません",in );
			return 1;
		}

		bufsize=bufsize*2;	

		free(data);
		data=(char*)malloc(sizeof(char)*bufsize);
		memset(data,'\0',sizeof(data));

		size = fread( data, 1,bufsize, fp ); 
		fclose( fp );
		if(bufsize>size)break;
	}

	p=data;

	while(1){
		//まずはコンテンツの長さを取得
		p=strstr(p,"Content-Length: ");
		if(p==NULL)break;	//ないなら抜ける
		p=p+16;
		ContentLength=atoi(p);

		//書き込み用バッファ準備
		output=(char*)malloc(sizeof(char)*ContentLength);
		memset(output,'\0',sizeof(output));

		//コンテンツの前まで移動
		p=strstr(p,"Connection: keep-alive");		
		p=p+25;

		//コンテンツをバッファへコピー
		memcpy(output,p,ContentLength);

printf("\n\n\n\n%d\n\n\noutput=-%s-\n\n",Count,output);				//確認用出力
getch();
		Count++;
		itoa(Count,Cbuf,10);
		strcat(Cbuf,".htlm");
		fp2 = fopen(Cbuf , "wb" );  
		if( fp2 == NULL )
		{
			printf( "%sが開けません" ,Cbuf);
			return 1;
		}

		//バッファをファイルへ書き込み
		fwrite( output, 1,ContentLength, fp2 ); 
		fflush(fp2);
		fclose( fp2 );
		free(output);
	}

	free(data);
	return 0;
}


int main(int argc,char *argv[]){

	SplitContent(argv[1]);

}


box
記事: 2002
登録日時: 15年前

Re: ファイルの書き込みでなぜか違うデータが書き込まれる

#2

投稿記事 by box » 13年前

shiro4ao さんが書きました: 試しにhttpレスポンスからhtmlボディを取り出すソフトを書いてみようと思いました。
fwrite()で出力したファイルの中身が違うのです。
HTML形式というテキストファイルを扱うために、
fwrite()というバイナリーファイル用の関数を使っているのはどうしてでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: ファイルの書き込みでなぜか違うデータが書き込まれる

#3

投稿記事 by みけCAT » 13年前

こちらの環境では誤動作はしませんでした。
gcc version 3.4.2 (mingw-special)
outputバッファをコンソールに書き出しているので、改行コードが変換されているのではないでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: ファイルの書き込みでなぜか違うデータが書き込まれる

#4

投稿記事 by みけCAT » 13年前

ついでに。
HTTPの仕様上、コンテンツの前まで移動するには

コード:

p=strstr(p,"Connection: keep-alive");       
p=p+25;
ではなくて

コード:

p=strstr(p,"\r\n\r\n");       
p=p+4;
だと思います。
現状のコードだと、Connection: closeだった場合、pにNULLが入ってアクセス違反になってしまいます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: ファイルの書き込みでなぜか違うデータが書き込まれる

#5

投稿記事 by beatle » 13年前

37行目のsizeof(output)はContentLengthと等しくなりませんが,ご承知の上でしょうか?

アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

Re: ファイルの書き込みでなぜか違うデータが書き込まれる

#6

投稿記事 by shiro4ao » 13年前

>fwrite()というバイナリーファイル用の関数を使っているのはどうしてでしょうか。
将来的に画像とかの処理もしようかなと思いバイナリが扱えるfwrite()にしました


>改行コードが変換されているのではないでしょうか?
この問題を忘れていました、すみません。
おそらく、改行コードがLinux系で、取り出すソフトはWin系なので
その違いだと思います。
ありがとうございます。すっきりしました。

環境を明記しておりませんでした。申し訳ありません。
HTTPレスポンスのログ取得はubuntu10.10
HTTPレスポンスからの取り出しソフトはWindows7 64bitです。


>Connection: closeだった場合、pにNULLが入ってアクセス違反になってしまいます。
ここも、区切りが探せなくて困っていたのですが、"\r\n\r\n"なのですね

>37行目のsizeof(output)はContentLengthと等しくなりませんが,ご承知の上でしょうか?
アッー!
またやってしまいました・・・・
ミスです。ContentLengthにしたかったのです・・・・

バイナリエディタでデータを確認したところ、バイナリデータで見るとちゃんと取り出せていたので
画像を貼ってあるサイトのHTTPレスポンスを読み込んだところ、うまく画像がでてきました。
ありがとうございます。

原因がわかったので一応これにて解決とさせて頂きます。

閉鎖

“C言語何でも質問掲示板” へ戻る