私はC++でプログラムを作成しています。このプログラムは、すべて同じディレクトリに格納されている多数(数千)のPPM画像を処理します。ただし、最初にピクセル値を読み込む必要があります。それらは、標準の名前空間に組み込まれている関数ですか、それともインポートできるライブラリで、ある種のループ構造を使用してファイル名をすでに知っていると想定せずに、一度にすべてのファイルを読み取ることができますか?それが違いを生む場合に備えて、私はMacでプログラムを書いています。
質問する
1510 次
1 に答える
1
インクルードと必要な依存関係を回避するためにboost::filesystem
、私はこの関数を実装することになりました。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
//include headers required for directory traversal
#if defined(_WIN32)
//disable useless stuff before adding windows.h
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include "dirent.h"
#endif
/**
Traverses the provided directory (non-recursively) and extracts the absolute paths to all the files in it.
Doesn't support non-ASCII file names.
@param directory the absolute path to the directory
@return a vector of file names (including extension)
*/
std::vector<std::string> Filesystem::GetFilesInDirectory(const std::string &directory)
{
std::vector<std::string> output;
#if defined(_WIN32)
//select all files
std::string tempDirectory = directory + "*";
//initialize the WIN32_FIND_DATA structure
WIN32_FIND_DATA directoryHandle = {0};
//set the directory
std::wstring wideString = std::wstring(tempDirectory.begin(), tempDirectory.end());
LPCWSTR directoryPath = wideString.c_str();
//iterate over all files
HANDLE handle = FindFirstFile(directoryPath, &directoryHandle);
while(INVALID_HANDLE_VALUE != handle)
{
//skip non-files
if (!(directoryHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//convert from WCHAR to std::string
size_t size = wcslen(directoryHandle.cFileName);
std::vector<char> buffer;
buffer.resize(2 * size + 2);
size_t convertedCharacters = 0;
wcstombs_s(&convertedCharacters, buffer.data(), 2 * size + 2, directoryHandle.cFileName, _TRUNCATE);
//trim the null characters (ASCII characters won't fill the vector, since they require fewer bytes)
//convertedCharacters includes the null character, which we want to discard
std::string file(buffer.begin(), buffer.begin() + convertedCharacters - 1);
//add the absolute file path
output.emplace_back(file);
}
if(false == FindNextFile(handle, &directoryHandle)) break;
}
//close the handle
FindClose(handle);
#else
DIR *directoryHandle = opendir(directory.c_str());
if (NULL != directoryHandle)
{
dirent *entry = readdir(directoryHandle);
while (NULL != entry)
{
//skip directories and select only files (hopefully)
//if ((DT_DIR != entry->d_type) && (DT_UNKNOWN == entry->d_type))
if (DT_REG == entry->d_type)
{
output.emplace_back(entry->d_name);
}
//go to next entry
entry = readdir(directoryHandle);
}
closedir(directoryHandle);
}
#endif
return output;
}
私は上記の柔軟性のない/ほとんど役に立たない/プラットフォームに依存するコードをあまり誇りに思っていません。可能であれば、間違いなくBOOSTを選びます。ちなみに、MACではテストされていないので、うまくいくかどうか教えてください。
于 2013-02-03T23:41:46.513 に答える