ディレクトリ内のすべてのファイル名を取得する

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

ディレクトリ内のすべてのファイル名を取得する

#1

投稿記事 by あかり » 11年前

ディレクトリ内のすべてのファイル名を取得したいのですが、どうすればいいかわかりません。
考えはvectorでstring型を確保して、ディレクトリ内のファイル名もしくは、フルパスを取得したいと思っています。
よろしくお願いします。

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

Re: ディレクトリ内のすべてのファイル名を取得する

#2

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

使用する言語とOSを教えてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

あかり

Re: ディレクトリ内のすべてのファイル名を取得する

#3

投稿記事 by あかり » 11年前

OS windows8 64
言語 C++
環境 Visual Studio 2013
です、よろしくお願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ディレクトリ内のすべてのファイル名を取得する

#4

投稿記事 by softya(ソフト屋) » 11年前

その環境だとWindowsAPIが定番ではないでしょうか。

「Win32API(C言語)編 第54章 ファイルを列挙する」
http://www.geocities.jp/ky_webid/win32c/054.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あかり

Re: ディレクトリ内のすべてのファイル名を取得する

#5

投稿記事 by あかり » 11年前

教えていただいたURLから必要な部分だけ取り出してみたのですが、

コード:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int main(void){
	HANDLE hSearch, hFile;
	WIN32_FIND_DATA fd;
	DWORD writeSize;
	TCHAR filename[MAX_PATH + 10];

		// ファイルを新規作成
	hFile = CreateFile(
		_T("filelist.txt"), GENERIC_WRITE, 0, NULL,
		CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
		);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return 0;
	}
			// 全てのファイルを列挙する
	hSearch = FindFirstFile(_T("D:/*.*"), &fd);
	if (hSearch == INVALID_HANDLE_VALUE)
	{
		return 0;
	}
	while (TRUE)
	{
		// 列挙されたファイル名を書き出す
		_tcscpy(filename, fd.cFileName); // ファイル名をバッファにコピー
		_tcscat(filename, _T("\r\n"));   // 末尾に改行文字を加える
		WriteFile(
			hFile, filename, (DWORD)(_tcslen(filename)*sizeof(TCHAR)),
			&writeSize, NULL
			);

		if (!FindNextFile(hSearch, &fd))
		{
			if (GetLastError() == ERROR_NO_MORE_FILES) 
				break;
			else 
				break;
		}
	}

	FindClose(hSearch);
	CloseHandle(hFile);

	return 0;
}

あかり

Re: ディレクトリ内のすべてのファイル名を取得する

#6

投稿記事 by あかり » 11年前

すいません、途中で送信してしまいました。
ソースなんですが、
_tcscpy(filename, fd.cFileName); // ファイル名をバッファにコピー
のところをstring型へ送るようにすればいいと思うのですが、
WIN32_FIND_DATAのデータをstring型にコピーするにはどうすればいいですか?

アバター
a5ua
記事: 199
登録日時: 15年前

Re: ディレクトリ内のすべてのファイル名を取得する

#7

投稿記事 by a5ua » 11年前

Visual Studio 2013なら<filesystem>を使うのがお手軽だと思います。

コード:

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

int main()
{
	std::vector<std::string> file_list;

	// カレントディレクトリ以下のファイル名を取得する
	// 再帰的にファイル名を取得する場合は、std::tr2::sys::recursive_directory_iteratorを使う
	for (std::tr2::sys::directory_iterator it("."), end; it != end; ++it) {
		file_list.push_back(it->path());
	}

	// 取得したファイル名をすべて表示する
	for (auto &path : file_list) {
		std::cout << path << std::endl;
	}
}

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

Re: ディレクトリ内のすべてのファイル名を取得する

#8

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

あかり さんが書きました:_tcscpy(filename, fd.cFileName); // ファイル名をバッファにコピー
のところをstring型へ送るようにすればいいと思うのですが、
WIN32_FIND_DATAのデータをstring型にコピーするにはどうすればいいですか?
std::string型はcharの配列で表現された文字列を代入するという表記が使えるので、ファイル名だけなら素直に

コード:

std::string filename_string;
filename_string=fd.cFileName;
でいいと思います。
WIN32_FIND_DATAのデータ全てをstd::string型にしたいなら、sprintfなどで文字列に変換する必要があります。
std::stringではなく、自作または他のライブラリのstring型なら、それに合った方法で変換すればいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ディレクトリ内のすべてのファイル名を取得する

#9

投稿記事 by softya(ソフト屋) » 11年前

<filesystem>はC++11のライブラリですね。
それが使えるなら、それで良いと思います。

ただ、charやwchar_tからstringへの代入変換もC++を使う以上は覚えたほうが良いと思いますよ。
と書いていたらみけCATさんが例を書いてましたね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あかり

Re: ディレクトリ内のすべてのファイル名を取得する

#10

投稿記事 by あかり » 11年前

皆さん、返信ありがとうございます。
filesystemを使った、ソースを使ってみようと思います。
それとなんですが、
みけCAT さんが書きました:
あかり さんが書きました:_tcscpy(filename, fd.cFileName); // ファイル名をバッファにコピー
のところをstring型へ送るようにすればいいと思うのですが、
WIN32_FIND_DATAのデータをstring型にコピーするにはどうすればいいですか?
std::string型はcharの配列で表現された文字列を代入するという表記が使えるので、ファイル名だけなら素直に

コード:

std::string filename_string;
filename_string=fd.cFileName;
でいいと思います。
WIN32_FIND_DATAのデータ全てをstd::string型にしたいなら、sprintfなどで文字列に変換する必要があります。
std::stringではなく、自作または他のライブラリのstring型なら、それに合った方法で変換すればいいと思います。
であったstring型なんですが、私も試してはみたのですが、ビルドエラーが起きていて使うことが出来ません。

エラー 1 error C2679: 二項演算子 '=' : 型 'WCHAR [260]' の右オペランドを扱う演算子が見つかりません (または変換できません)。

と表示されています。
a5uaさんのソースで解決はしたのですが、ここをどうすればいいか教えてもらえませんか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: ディレクトリ内のすべてのファイル名を取得する

#11

投稿記事 by h2so5 » 11年前

文字セットをUnicodeからマルチバイトに変えてください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ディレクトリ内のすべてのファイル名を取得する

#12

投稿記事 by softya(ソフト屋) » 11年前

文字コードセットがUNICODEになっているので、WCHARマクロ=wchar_t型でコンパイルされている様です。
この場合は、char文字セットのstd::stringではなく、std::wstringを使います。
※ ただしTCHARで決め打ちは良くないのですがマイクロソフトがtstringを作っていないので困ったものです。

こうして解決する方法もあります。
「その14 UNICODEで分けないtstring型を宣言する」
http://marupeke296.com/TIPS_No14_tstring.html

文字コードに関しては勉強されることをおすすめします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あかり

Re: ディレクトリ内のすべてのファイル名を取得する

#13

投稿記事 by あかり » 11年前

文字コードでコンパイルされるのも変わるんですね、ありがとうございます。
皆さんのおかげで解決しました、ありがとうございました!

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ディレクトリ内のすべてのファイル名を取得する

#14

投稿記事 by softya(ソフト屋) » 11年前

あかり さんが書きました:文字コードでコンパイルされるのも変わるんですね、ありがとうございます。
皆さんのおかげで解決しました、ありがとうございました!
TCHAR系はマイクロソフト独自の変則仕様である事をお断りしておきます。
gccなど他のコンパイラでは通用しないので覚えておいて下さいね。
例えばLinuxやAndroid NDKで使うとひどい目に合います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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