パッキングについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たぬき

パッキングについて

#1

投稿記事 by たぬき » 11年前

以下のサイトにて,
http://1st.geocities.jp/shift486909/pro ... cking.html
パッキングの勉強をしているのですが,
Pack.cpp内のserch関数に書かれている

コード:

void search(string path, vector<BYTE> &buf){
~略
	//検索準備
	find_it = _findfirst((path + "*.*").c_str(), &find);
	if (find_it == -1){
		throw "パスが無効です";
	}

	//ゴミデータ読み飛ばし
	_findnext(find_it, &find);
略~
部分の

コード:

//ゴミデータ読み飛ばし
	_findnext(find_it, &find);
がなぜ必要なのかがわかりません.
ただ,この部分をコメントアウトしてみると,
その上の/検索準備にある”パスが無効です”が出力されます.

そもそもなぜディレクトリ内の先頭の次(_findnext)にゴミデータが含まれているのか,
また,どうしてここのコードをコメントアウトすると,それよりも前で実行されるはずのコード内容(~throw "パスが無効です";)が出力されるのかを教えていただきたいです.

リンク先の方にもコードが載っていますが,一応こちらの方にも載せておきます.

コード:

//main.cpp
#include "pack.h"

int main(int argc,char *argv[]){
	
	if(argc<2){
		cout<<"ファイルをドラッグドロップしてください"<<endl;
		getchar();
	}

	try{
		string path=argv[1];
		string ext;
		string::iterator it=find(path.begin(),path.end(),'.');

		copy(it,path.end(),back_inserter(ext));

		if(it==path.end()){//ディレクトリなら
			pack(path);
		}
		else if(ext==EXT){//".pak"ファイルなら
			dispack(path);
		}
		else{
			cout<<"ディレクトリ または \".pak\"ファイルを"<<endl;
			cout<<"ドラッグドロップしてください"<<endl;
			getchar();
		}
	}
	catch(const char *e){
		cout<<e<<endl;
		getchar();
	}

	return 0;
}

//pack.cpp
#include "pack.h"

void search(string path,vector<BYTE> &buf);
string root;

//ファイル(ディレクトリ)をパックする
UINT pack(string path){
	setlocale(LC_ALL,"japanese");

	//変数宣言
	//ファイルデータ
	vector<BYTE> buf;
	string outpath=path+EXT;

	root=path;

	search(path,buf);

	ofstream fout(outpath.c_str(),ios::binary);
	fout.write((char*)&buf[0],buf.size());

	return 0;
}

void search(string path,vector<BYTE> &buf){

	FIND find;
	FIND_IT find_it;

	//パスの最後が'\'で終わってなかったら付け足す
	if(*(path.end()-1)!='\\'){
		path+='\\';
	}

	//検索準備
	find_it=_findfirst((path+"*.*").c_str(),&find);
	if(find_it==-1){
		throw "パスが無効です";
	}

	//ゴミデータ読み飛ばし
	_findnext(find_it,&find);

	//サーチ
	for(;_findnext(find_it,&find)==0;){
		if(find.attrib & _A_SUBDIR){//サブディレクトリ
			//ディレクトリヘッダーを入れる
			string direct,h;
			ostringstream trans;
			direct=path;
			direct=direct.replace(0,root.length(),"")+find.name;
			
			trans<<"0\t"<<direct<<"\t";
			h=trans.str();

			//バッファにヘッダーを書き込む
			copy(h.begin(),h.end(),back_inserter(buf));

			search(path+find.name,buf);//再帰
		}
		else{//ファイル
			//変数宣言
			string file,h;
			ostringstream tranc;
			UINT size=0;

			//ファイル名
			file=path+string(find.name);
			//ファイルオープン
			ifstream fin(file.c_str(),ios::binary);

			if(fin.fail()){//エラーチェック
				throw "ファイル読み込みエラー";
			}
			//ファイルのサイズを取得
			size=fin.seekg(0,ios::end).tellg();

			string direct=path;
			direct=direct.replace(0,root.length(),"")+find.name;
			//UINT型をstringに変換するため
			//ストリングストリームにヘッダーを詰め込む('\t'タブ区切り)
			tranc<<size<<"\t"<<direct<<"\t";
			//ヘッダーをstringで取得
			h=tranc.str();
			//バッファにヘッダーを書き込む
			copy(h.begin(),h.end(),back_inserter(buf));

			//バッファのメモリを確保
			buf.resize(buf.size()+size);
			//ファイルデータをバッファに書き込む
			fin.seekg(0,ios::beg).read((char*)&buf[buf.size()-size],size);
		}
	}

	//検索終了
	_findclose(find_it);

}

//pack.h
//インクルードファイル
#include <iostream>
#include <IO.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <direct.h>

using namespace std;

//typedef宣言
typedef unsigned char BYTE;
typedef unsigned int UINT;
typedef _finddata_t FIND;
typedef intptr_t FIND_IT;

//マクロ定義
#define EXT ".pak"

//プロトタイプ宣言
UINT pack(string path);
UINT dispack(string path);

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

Re: パッキングについて

#2

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

find.nameを出力してみるとわかりますが、_findfirstで"."が、「ゴミデータ読み飛ばし」で".."が入っていました。
ただ、必ずここに"."と".."が来る(環境依存しない)のかはわかりません。

コード:

// path.cppの最初に#include <cstdio>を追加

void search(string path,vector<BYTE> &buf){

	FIND find;
	FIND_IT find_it;

	//パスの最後が'\'で終わってなかったら付け足す
	if(*(path.end()-1)!='\\'){
		path+='\\';
	}

	printf("begin search %s\n",path.c_str());
	//検索準備
	find_it=_findfirst((path+"*.*").c_str(),&find);
	if(find_it==-1){
		throw "パスが無効です";
	}
	printf("first %s\n",find.name);

	//ゴミデータ読み飛ばし
	_findnext(find_it,&find);
	printf("gomi %s\n",find.name);

	//サーチ
	for(;_findnext(find_it,&find)==0;){
		printf("search %s\n",find.name);
		if(find.attrib & _A_SUBDIR){//サブディレクトリ

			// 以下略
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

たぬき

Re: パッキングについて

#3

投稿記事 by たぬき » 11年前

返信ありがとうございます.

printf()で確認すればよかったですね.すいません.

".",".."について調べてみたのですが,

引用:(http://www.ssl.nd.chiba-u.jp/~koakutsu/JouSyo/file.html
カレントディレクトリ:
現在作業対象としているディレクトリ, “.”(ピリオド1個)
親ディレクトリ:
上位のディレクトリ,“..”(ピリオド2個)

と書かれているページがありました.
この現在作業対象としているディレクトリと上位のディレクトリが引っかかっているとみてよろしいでしょうか?

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

Re: パッキングについて

#4

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

たぬき さんが書きました:この現在作業対象としているディレクトリと上位のディレクトリが引っかかっているとみてよろしいでしょうか?
よさそうだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

たぬき

Re: パッキングについて

#5

投稿記事 by たぬき » 11年前

空っぽのディレクトリでも,気をつけないことがあるんですね.
勉強になりました.

みけCATさん,丁寧なご回答ありがとうございました.

閉鎖

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