• ベストアンサー

ファイル名の取得について

フォルダAとフォルダBに同じ名前のファイルが存在するか調べるPRGを考えています。 私の今までのやり方だと、フォルダからファイル名を一つづつ取り出し、その都度ファイル名が同じか判断していました。 しかし、この方法だとファイルが多いと時間が掛かると思われるため、最初にフォルダにあるファイル名をすべて取り出し、その後一つづつファイル名を比較しようと考えています。 この最初にファイル名をすべて取り出し、配列に代入する方法がよく判りません。 というか、配列に入れれば良いかもよく判りません。 ということで、簡単なコードなり、ヒントなり、参考になるサイトなり教えていただけるとありがたいです。

  • mk1234
  • お礼率94% (1832/1940)

質問者が選んだベストアンサー

  • ベストアンサー
  • me_no_car
  • ベストアンサー率24% (22/90)
回答No.3

C言語では動的にメモリを確保する必要があります。 動的メモリ確保で検索するといろいろでてくる と思いますよ。 ファイル名を取得し配列に格納する サンプルソースのせておきます。 ちなみにディレクトリ名の取得はUNIX-Cです。 補足説明としては2回目以降はreallocでメモリ再確保 するのがポイントです。 連続したアドレスでメモリ確保してくるので別途アドレス を確保しておく必要もないし配列と同様に扱えます。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dirent.h> ---------------------------- int cnt=0; char DirPath[256]; char **filename; DIR *dir; struct dirent *dp; strcpy(DirPath,"ここに検索対象ディレクトリ"); dir = opendir(DirPath); while( (dp = readdir(dir)) != NULL ){ if( cnt == 0 ){ filename = (char **)malloc(sizeof(cnt + 1 )); } else{ filename = (char **)realloc(filename,sizeof(cnt + 1 )); } *(filename + cnt ) = (char *)malloc(sizeof(strlen(dp->d_name) + 1 )); *(filename + cnt) = dp->d_name; cnt++; } closedir(dir); -------------------------------------------

mk1234
質問者

お礼

回答ありがとうございます。 あとで知人から聞いたのですが、ファイル名の取得ぐらいなら2万件あってもたいしたことないので、mallocを使うより最大ファイル数を設定するほうが一般的らしいのですがそうなのでしょうか? (ケース バイ ケースなのでしょうが・・・)

その他の回答 (4)

  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.5

こんにちわ。 全てのファイルを取り出して配列に格納しようとすると、 ファイルの数だけメモリを獲得する必要があるので 配列を使用しない方が良いと思いますょ。 具体的には、  1) フォルダA の下にあるファイル名を1つ取得  2) フォルダB に1) で取得したファイルがあると仮定    して、フルパスを作成  3) OpenFile 又は CreateFile で2) で作成した    フルパスをオープン  4) 正常にオープンできれば、同じ名前のファイルがある    と判断できる。  5) フォルダA の下のファイルを全て処理し終わるまで    1) 以下を繰り返し でどうでしょう?

mk1234
質問者

お礼

回答ありがとうございます。 なかなか面白そうなアイデアですね。 本当は、同じファイル名の捜索ではなく、同じファイル内容の捜索を行いたかったのですが、話を簡単にするためと、配列の扱いが知りたかったため最初の質問をしました。 有名な???AIKO for Win32と同じソフトを自作したかったのです。 今はDL出来なくなっているみたいですね。 昔はソースコードも公開されてると聞いたのですが、どなたか持っている人がいたら、送ってもらえませんかね。 こういうことは、作者に対し失礼なのでしょうか?

noname#30727
noname#30727
回答No.4

>私の今までのやり方だと、フォルダからファイル名を一つづつ取り出し、その都度ファイル名が同じか判断していました。 フォルダAから1つづつ取り出すときに "folderA\\*" など(Windows系の場合)で検索してますよね? 見つかったファイルが "filename.txt" だとしたら、すぐに "folderB\\filename.txt" でファイル検索すれば比較する手間もないですし、速度的にも気になるほどでもないと思います。 vector<string> と同等のものを作るのは大変ですが、機能限定ならそうでもないかも。 #include <stdio.h> #include <malloc.h> #include <string.h> typedef struct { int count; int limit; char **list; } svec; void init_svec(svec *v) { v->count = 0; v->limit = 0; v->list = NULL; } void add_svec(svec *v, const char *s) { char **temp; if (v->limit == 0) { v->limit = 1; v->list = (char**)malloc(sizeof(char*)); } else if (v->limit == v->count) { v->limit *= 2; temp = (char**)malloc(sizeof(char*) * v->limit); memcpy(temp, v->list, sizeof(char*) * v->count); free(v->list); v->list = temp; } v->list[v->count] = (char*)malloc(strlen(s) + 1); strcpy(v->list[v->count], s); v->count++; } void free_svec(svec *v) { int i; for (i = 0; i < v->count; i++) { free(v->list[i]); } if (v->limit) { free(v->list); } init_svec(v); } int main() { svec v; int i; init_svec(&v); add_svec(&v, "Black"); add_svec(&v, "Silver"); add_svec(&v, "Gray"); add_svec(&v, "White"); add_svec(&v, "Red"); add_svec(&v, "Purple"); for (i = 0; i < v.count; i++) { printf("%s\n", v.list[i]); } return 0; }

mk1234
質問者

お礼

回答ありがとうございます。 皆さんにいろいろ教えて頂いてこう言うのもなんですが、ファイル名を1つ取り出すたびに比較(あるいは検索)してもそう問題ないのかな?って気がしてきました。 なぜなら動的メモリの確保もそのつどメモリを確保し直すわけだし。 個人的に使うソフトのため、今回はこれで良しとさせてください。 もちろん、教えていただいたコードや考え方はしっかり勉強させていただきます。 ありがとうございました。

回答No.2

回答になっていません(多分)。 > 例えばキーボードから任意の個数の任意の長さの文字列を一つ入力するたびにエンターキーを押すような場合、 > 配列に文字列を格納するにはどのようにすれば良いのでしょう? 標準C++的には "配列なんか使いません" #include <iostream> #include <vector> #icnlude <string> using namespace std; int main() { vector<string> inputs; string line; while ( getline(cin, line) ) { inputs.push_back(line); } ... return 0; } > 必要配列の個数と必要文字列長さを入力時に動的に求める方法が知りたいです。 標準C++的には "クラスに考えてもらいます" # Cでどうするかは...他の方の回答を待ちます。

mk1234
質問者

お礼

すばやい回答ありがとうございます。 C言語で配列の場合はどうするのでしょう? よろしくお願いします。

回答No.1

#include <windows.h> #include <iostream> #include <string> #include <iterator> #include <set> #include <algorithm> template<typename OutIter> OutIter enumfiles(const std::string& path, OutIter result) { WIN32_FIND_DATA fd; HANDLE handle = FindFirstFile(path.c_str(), &fd); if ( handle == INVALID_HANDLE_VALUE ) return result; do { *result++ = fd.cFileName; } while ( FindNextFile(handle, &fd) ); FindClose(handle); return result; } // dir_a, dir_b の双方にあるファイル名を出力。 int main(int argc, char* argv[]) { std::set<std::string> fn1, fn2; enumfiles("d:\\dir_a\\*.*", std::inserter(fn1,fn1.end())); enumfiles("d:\\dir_b\\*.*", std::inserter(fn2,fn2.end())); std::set_intersection(fn1.begin(), fn1.end(), fn2.begin(), fn2.end(), std::ostream_iterator<std::string>(std::cout,"\n")); return 0; }

mk1234
質問者

お礼

epistemeさん 回答ありがとうございます。 私にとっては、ちょっと見慣れないコードが多いのであとでゆっくり理解します。

mk1234
質問者

補足

自分でも当然調べますが、もう少し基本的な方法として、 例えばキーボードから任意の個数の任意の長さの文字列を一つ入力するたびにエンターキーを押すような場合、配列に文字列を格納するにはどのようにすれば良いのでしょう? 必要配列の個数と必要文字列長さを入力時に動的に求める方法が知りたいです。 <補足> 多分判っている人にとっては、すごく基本的なことのような気がするのですが、私は今までこのようなことをやったことがないので”教えてあげましょう”と思われた方よろしくお願いします。

関連するQ&A

  • フォルダ内のファイル名を取得する

    windows 7なのですが、フォルダ内にあるファイル名をテキストとしてすべて一括で取得する方法はないでしょうか? また、フォルダの中にさらに複数のフォルダがあっても、上の階層のフォルダからすべてファイル名を取得する方法はないでしょうか? よろしくお願いいたします。

  • C# ファイルサイズの取得(ファイル名ではない)

    ファイルサイズ取得で検索するとファイル名のサイズを取得する方法ばかりで実際に存在しているファイルの大きさと合っていないのですが、どのようにコードを書けば良いでしょうか?

  • ファイル名の始めに“.”をつけてしまい消えた

    AndroidのSDマネージャーで隠しフォルダを作るときに、フォルダ名ではなく、ファイル名の最初に“.”を付けてしまい、すべてのファイルを表示にしても見れなくなりました。 消えてしまったのでしょうか?

  • フォルダーの中のファイル名を取り出す

    フォルダーの中のファイル名を取り出し配列に格納する方法はありますか?

  • フォルダ内にあるファイル名を取得したい

    cを利用して、指定したフォルダの中にある全てのファイルの名前を取得するプログラムを作りたいのですが、適した関数がわかりません。 指定するフォルダはあらかじめ決めうちで、その中には.txtのファイルのみを格納します。 どなたか教えてください。できれば自分で作りたいのでヒントをください。お願いします。 VisualC++.netを使っています。OSはXPです。

  • delphi5でのディレクトリ内ファイル名の取得

    こんにちは。質問があります。 delphiのアプリケーションであるディレクトリのフォルダ内のファイルを 別のディレクトリのフォルダ内に名前を変えてコピーしようと考えています。 基本的にコピー元のディレクトリ名はわかりません。 コピー先のディレクトリは存在しなければ、名前を指定して作成し、その中に名前を変更したファイルを格納する流れです (わかりづらいかも・・・) フォルダが存在しなければ作成したり、ファイル名を変更してコピーする のはわかったのですが、コピー元のディレクトリ内のファイル(もしくはディレクトリ)名を取得することがわかりません。 全てソースの中でプログラムしたいと考えています。(VCLは使用しない) こんなんでもわかっちゃったりする方がいらっしゃいましたら、 どうか愛の手を・・・

  • フォルダの全ファイル名を自動的に取り込むには

    ビジュアルベーシク(VB5)でドライブ、フォルダ、ファイルの各アイコンをフォームに配置して動作させると、手動でファイル名を取得できますが、フォルダを指定したらその中のファイル名全てを、自動的に文字配列変数に取り込むにはどうしたらよいでしょうか?よろしくお願いします。

  • フォルダに入っているファイルの取得

    フォルダ/abcに入っている、JPGの画像のファイルを配列@defに取得するコードをお願いします。

    • ベストアンサー
    • Perl
  • ファイルの拡張子を取得したい

    あるフォルダにファイルが存在しています。ファイルが存在していることは確認できています。 ファイル名まではわかっているのですが、拡張子がわかりません。 実在するファイルの拡張子を取得する方法を教えてください。

    • 締切済み
    • PHP
  • 同じファイル名なのに同じと判定しない

    重複データを削除するために、有名どころであるFileManyというフリーソフトを使っているのですが、同じファイル名なのに同じと判定しないことがあります。 エクスプローラーや別の同様なアプリでは同じ名前と判定します。 人の目で見ても当然同じファイル名です。 フォルダ階層も深くないですし、ファイル数も1個で比較してもダメです。 プログラムのコードは知りませんが、普通に考えて、パスからファイル名を抜き出し、if文で比較しているだけだと想像します。 ほぼ正しく動くのに、例外的に動かないことが(バグ)あると困りますよね。 なぜこんなことが起きてしまうのでしょうか?

専門家に質問してみよう