
やりたい事は、ファイル(テキストに限らず画像等も含めて)をfopen関数で読み込んであらかじめ用意したバッファーに格納されているデータと一致する箇所をすべて検索して検索されたところをすべて列挙することです。
効率の良い(検索速度)方法で行いたいのですが、
fgetc関数を使って検索していくのとfread関数を使って一度すべてをメモリー内に読み込んで検索するのではどちらが効率がよいでしょうか?
他にも良い方法があったら教えてください。
私はFILE * ストリームポインタの仕組みがよくわかっていません。fopenをすると何が内部で行われるのでしょうか?ファイルの内容がメモリーに読み込まれるわけではないですよね?ファイル内にアクセスする時どのようにアクセスしているのかなど教えていただきたいです。そうすればどうするのが良いのかわかる気がするので。
あとこれとは別の話ですが
標準関数にあるmemmoveとstrstr関数ですが、これと同様な機能を持つstrmoveとmemmemといった関数がなかったのですが、この機能を持つ関数は用意されているのでしょうか?一般的に使われないので自分で作れということなのでしょうか?その場合どの様に実装すればよいか時間があれば参考にプログラムを書いていただけないでしょうか?
よろしくお願いします。
No.4ベストアンサー
- 回答日時:
>fgetc関数を使って検索していくのとfread関数を使って一度すべてをメモリー内に読み込んで検索するのではどちらが効率がよいでしょうか?
→一番早い検索は全てメモリに読み込み,ファイルアクセス回数を減らすのが基本です。ファイルアクセスにはOSの処理時間が発生する為です。
ただ,ファイルが大きすぎてメモリに入りきらない場合もありますので,ファイルの大きさを見てファイルのアクセス方法を変えるしかないと考えます。
ちなみにパソコンのOS環境下では,fgetc関数を使っても毎回物理的にファイルを読み込んでいるわけではなく,ファイルバッファを読み込む事になりますので思ったほどは効率が悪くなりませんが,高速化を考えた場合はfread関数を使うことをおすすめします。
>私はFILE * ストリームポインタの仕組みがよくわかっていません。fopenをすると何が内部で行われるのでしょうか?
→お使いの環境(OS)によってはfopenの内部動作は変わってくるかもしれませんが。手元の環境での動作についてまとめます。
・ファイルオープン
OSが提供しているファイルオープン関数(createfile関数とか_open関数など)を使いファイルをオープンします。
・ファイル読み込み用のバッファ構造の提供
これはfgetc関数,fread関数,fscanf関数などファイル読み込みをバッファ経由で行いファイル読み込み回数を減らす機能を提供します。
・FILE型のリソース確保
ファイルオープン時にFILE型のリソースを確保し戻り値に確保したアドレスを返します。
>ファイルの内容がメモリーに読み込まれるわけではないですよね?ファイル内にアクセスする時どのようにアクセスしているのかなど教えていただきたいです。そうすればどうするのが良いのかわかる気がするので。
→普通fopen関数ではファイルの読み込みは行われません。fgetc関数なりfread関数がコールされた場合に,バッファが空の時に適当なサイズ分を低水準入出力(_read)関数などを使いバッファへ読み込みを行い,そこから結果を返しています。またバッファにデータがある場合はバッファから直接結果を返しています。
>標準関数にあるmemmoveとstrstr関数ですが、これと同様な機能を持つstrmoveとmemmemといった関数がなかったのですが、この機能を持つ関数は用意されているのでしょうか?一般的に使われないので自分で作れということなのでしょうか?
→必要であれば必要に応じて作るという認識だと思います。
>その場合どの様に実装すればよいか時間があれば参考にプログラムを書いていただけないでしょうか?
#define strmove(A, B) memmove((A), (B), (strlen(B) + 1) * sizeof(char))
// 引数 : strLen pStrのサイズ , pSrc 検索対象の先頭アドレス , searchLen pSearchのサイズ , pSearch 検索するデータの先頭アドレス
char *memmem(int strLen, char *pStr, int searchLen, char *pSearch)
{
// 単純検索 世の中にはBM法とかKMV法など色々と検索するロジックが存在します。高速化をしたいのであればそちら検討して下さい。
int i;
if (strLen < searchLen) return NULL;
for ( i = 0; i < strLen - searchLen + 1; i++) {
if ( memcmp(&pStr[i], pSearch, searchLen) == 0 ) {
return &pStr[i];
}
}
return NULL;
}
回答ありがとうございます。
やはり一度すべて読み込んだ方が速かったです。
説明を読んで納得できました。
検索アルゴリズムをいままで書いたこと無かったのでネットで検索してBM法とBMH法とquick search法をでそれぞれ作ってみました。
単純検索より速く検索でき驚きました。
memmem関数を自力で作ることができました。助かりました。
No.3
- 回答日時:
先にfreadで全部読み込む方法の場合、メモリ管理がやや面倒になります。
事前にファイルサイズを調べておけばよいのですが、標準の範囲ではいったん最後まで読むしかないので、あまりうれしくありません。アルゴリズムにもよりますが、ごく単純なものであればfgetcを使って1バイトずつ読み込みながら検索するほうが、作るのも簡単ですし、実行効率もよくなる可能性があります(実行効率に付いては実装方法次第です)。
memmoveというのは、領域の重なり方に応じて、前から後ろに向かってコピーするか、後ろから前に向かってコピーするかを切り替えています。これを実現するには、領域のサイズが分かっていなければなりません。
したがって、strmoveのようなものを作ろうとすると、いったんstrlenで文字列の長さを調べてからmemmoveすることになります。
具体的には、
memmove(s1, s2, strlen(s2));
のような感じです。これだけで済みますので、特別な関数は不要でしょう。
回答ありがとうございます。
いろいろアルゴリズムを考えようとおもい一度すべてメモリに読み込むことにしました。確かに単純なものならgetcが手っ取り早いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 顧客ごとに違う点検案内を作成するマクロ 4 2022/09/16 05:34
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- WordPress(ワードプレス) WordPressのサイトにPDFをアップロードした際にGoogleなどの検索結果に出ないでほしい 1 2022/08/03 10:44
- Visual Basic(VBA) vbaサブフォルダーをワイルドカードで取得したい 2 2022/11/15 08:04
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- 副業・複業 『Webライター』になりたいです。 まずブログSNS副業に興味関心がありました。 そして大きな目標と 14 2023/06/16 14:01
- Visual Basic(VBA) VBA 検索と入力 Excel ブック ぶぶぶ シート ししし 列V 検索対象の列です 最終行は、お 6 2023/05/17 01:40
- C言語・C++・C# プログラム内から、MIDIファイルの一部分だけを再生する方法 1 2023/02/15 11:08
- ドライブ・ストレージ 家庭用のNASについて 2 2022/07/05 18:30
- C言語・C++・C# このプログラミング誰か教えてくれませんか 3 2022/05/13 17:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
グローバル変数のよくない使い...
-
ファイル名の先頭にアンダース...
-
csvファイルを開かずに文字を検...
-
ダイアログボックスで複数フォ...
-
ファイルの結合
-
CSVファイルへの保存の際、デー...
-
COM相互運用機能のON,OFFによる...
-
VBに、Cのincludeのようなもの...
-
Wordファイルの結合
-
ハッシュの計算時間について
-
Access2010の最適化設定について
-
最近使ったファイルからファイ...
-
simplexml_load_fileのタイムア...
-
ExcelVBA 定数宣言を外部ファイ...
-
テキストファイルの文字化けに...
-
ファイル読み書き方法について...
-
fopenできる上限の変更
-
バイナリーデータをCSV変換して...
-
ShellExecuteEx→WaitForSingleO...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
dataファイルをxtxファイルにす...
-
csvファイルを開かずに文字を検...
-
ファイル名の先頭にアンダース...
-
CSVファイルへの保存の際、デー...
-
グローバル変数のよくない使い...
-
バッチで118項目のCSVを処理し...
-
テキストファイルの最終行を削...
-
VBAにてEXCEL以外のファイル(テ...
-
VBに、Cのincludeのようなもの...
-
分割コンパイルの#defineについて
-
RPGでファイル名(もしくはレコ...
-
SGファイルって何ですか?
-
マウスポインタの変更
-
Excelマクロでの再読込み方法
-
【C#】リソースファイルの埋め...
-
ダイアログボックスで複数フォ...
-
C言語のfopenについて教えてく...
-
ドラッグアンドドロップでファ...
-
「VBScript」ADODB.Streamにお...
おすすめ情報