সি বা সি ++ ব্যবহার করে কোনও ডিরেক্টরিতে থাকা ফাইলগুলির তালিকা আমি কীভাবে পেতে পারি?


592

আমি আমার সি বা সি ++ কোডের ভিতরে থেকে কোনও ডিরেক্টরিতে থাকা ফাইলগুলির তালিকা কীভাবে নির্ধারণ করতে পারি?

lsকমান্ডটি কার্যকর করতে এবং আমার প্রোগ্রামের মধ্যে থেকে ফলাফলগুলি বিশ্লেষণের অনুমতি নেই।




1
@ ক্রিশ - হ্যাঁ তবে এইটির ক্লাসিক রয়েছে "আমাকে 'এলএস' চালানোর অনুমতি নেই"! এটা ঠিক আমি কম্পিউটার সায়েন্স এর 1 ম বর্ষ মনে চাই। ; ডি <3 এক্স
জেমস বেডফোর্ড

1
সি এবং সি ++ একই ভাষা নয়। সুতরাং, এই কাজটি সম্পাদন করার পদ্ধতি উভয় ভাষায় আলাদা হবে। দয়া করে একটি চয়ন করুন এবং সেই অনুযায়ী পুনরায় ট্যাগ করুন।
এমডি এক্সএফ

2
এবং সেগুলির কোনওটিরই নয় (সি ++ অন্যান্য সি ++ এর বাইরে) এমনকি একটি ডিরেক্টরিের ধারণাও নেই - সুতরাং কোনও উত্তর সম্ভবত আপনার ওএসের উপর নির্ভর করে, বা আপনি যে কোনও অ্যাবস্ট্রাকশন লাইব্রেরি ব্যবহার করছেন তা নির্ভর করে।
টবি স্পিড

উত্তর:


809

ছোট এবং সাধারণ কাজগুলিতে আমি বুস্ট ব্যবহার করি না, আমি ডায়রেন্ট h ব্যবহার করি যা উইন্ডোজের জন্যও উপলব্ধ:

DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\src\\")) != NULL) {
  /* print all the files and directories within directory */
  while ((ent = readdir (dir)) != NULL) {
    printf ("%s\n", ent->d_name);
  }
  closedir (dir);
} else {
  /* could not open directory */
  perror ("");
  return EXIT_FAILURE;
}

এটি কেবলমাত্র একটি ছোট্ট হেডার ফাইল এবং বুস্টের মতো কোনও বড় টেম্পলেট-ভিত্তিক পদ্ধতির ব্যবহার না করে আপনার প্রয়োজনীয় সাধারণ জিনিসগুলির বেশিরভাগই কাজ করে (কোনও অপরাধ নয়, আমি বুস্টকে পছন্দ করি!)।

উইন্ডোজ সামঞ্জস্যতা স্তরটির লেখক হলেন টনি রনক্কো। ইউনিক্সে এটি মানক শিরোনাম।

আপডেট আপডেট 2017 :

C ++ 17 এখন আপনার ফাইল সিস্টেমের তালিকা ফাইলগুলিতে একটি সরকারী উপায় হল: std::filesystem। এই উত্স কোড সহ নীচে শ্রীবর্ধনের একটি দুর্দান্ত উত্তর রয়েছে :

#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main()
{
    std::string path = "/path/to/directory";
    for (const auto & entry : fs::directory_iterator(path))
        std::cout << entry.path() << std::endl;
}

5
@ আর্টঅফওয়ারফেয়ার: এই প্রশ্নের উত্তর দেওয়া হলেও ছোট্ট ডিডির তৈরি করা হয়নি। এছাড়াও এটি ড্রেইন্ট (পসিক্স) এবং ফাইন্ডফার্সফায়াল (উইন্ডোজ) এর চারপাশে একটি মোড়ক রয়েছে, তবে ডায়রেন্ট। কেবল উইন্ডোজের জন্য ডাইরেন্টকে মোড়ক দেয়। আমি এটি একটি ব্যক্তিগত স্বাদ বলে মনে করি, তবে ডাইরেক্ট ড। স্ট্যান্ডার্ড হিসাবে আরও বেশি অনুভব করে
পিটার পার্কার

7
@ জোশসি: কারণ * এনট অভ্যন্তরীণ উপস্থাপনের কেবলমাত্র ফিরে আসা পয়েন্টার। ডিরেক্টরিটি বন্ধ করে আপনি * এনটকেও মুছে ফেলবেন। যেহেতু * এন্টটি কেবল পড়ার জন্য, এটি একটি বুদ্ধিমান নকশা, আমার ধারণা।
পিটার পার্কার

42
মানুষ বাস্তব পেতে !! এটি ২০০৯ সালের একটি প্রশ্ন এবং এটি ভিএস-র উল্লেখও করেনি সুতরাং সমালোচনা করবেন না যে আপনার সম্পূর্ণ মালিকানাধীন (যদিও বেশ সুন্দর) আইডিই বহু শতাব্দী পুরানো ওএস মানকে সমর্থন করছে না। এছাড়াও আমার উত্তরটি জানায় যে এটি উইন্ডোজের জন্য "উপলব্ধ", এখন থেকে এবং সর্বকালের জন্য কোনও আইডিইতে "অন্তর্ভুক্ত" নয় ... আমি দৃ sure়ভাবে নিশ্চিত যে আপনি ডাইরেন্টটি ডাউনলোড করতে এবং এটিতে কিছুটা দির এবং ভয়েলা অন্তর্ভুক্ত করতে পারেন।
পিটার পার্কার

6
উত্তরটি বিভ্রান্তিকর। এটি দিয়ে শুরু করা উচিত: " ... আমি ডায়রেন্ট। H ব্যবহার করি , যার জন্য উইন্ডোজ ওপেন-সোর্স সামঞ্জস্যতা স্তরটিও বিদ্যমান "।
rustyx

10
সি ++ 14 এর সাথে রয়েছে std::experimental::filesystem, সি ++ 17 রয়েছে std::filesystem। নীচে শ্রীবর্ধনের উত্তর দেখুন। সুতরাং তৃতীয় পক্ষের গ্রন্থাগারের প্রয়োজন নেই।
ড্যান্টন

346

সি ++ 17 এর এখন একটি রয়েছে std::filesystem::directory_iterator, যা হিসাবে ব্যবহার করা যেতে পারে

#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    std::string path = "/path/to/directory";
    for (const auto & entry : fs::directory_iterator(path))
        std::cout << entry.path() << std::endl;
}

এছাড়াও, std::filesystem::recursive_directory_iteratorউপ-ডিরেক্টরিগুলিও পুনরাবৃত্তি করতে পারে।


27
আমি যতদূর জানি এছাড়াও সি ++ 14 ব্যবহার করা যাবে, কিন্তু এটি এখনও পরীক্ষামূলক হল: namespace fs = std::experimental::filesystem;। এটি ঠিক আছে বলে মনে হচ্ছে।
পিটারকে

7
এটি বর্তমান ব্যবহারের জন্য পছন্দসই উত্তর হওয়া উচিত (সি ++ 17 দিয়ে শুরু হওয়া)
গ্রীন ডায়োড

4
যখন পাস std::filesystem::pathকরার দিকে মনোযোগ দিন std::cout, উদ্ধৃতি চিহ্নগুলি আউটপুটে অন্তর্ভুক্ত থাকে। এটি এড়াতে, অন্তর্ভুক্ত .string()রূপান্তর (এখানে std::cout << p.string() << std::endl;) পরিবর্তে একটি স্পষ্ট করে করার পথে যুক্ত করুন । উদাহরণ: coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3
ড্যান্টন

2
ফাইলের নাম নন-এএসসিআইআই অক্ষর সম্পর্কে কী? std::wstringব্যবহার করা উচিত নয় বা পুনরুক্তিকারী থেকে প্রকারটি কি?
অ্যান্ডেরো

2
আমি এতে একা আছি কিনা তা নিশ্চিত নই, তবে লিঙ্ক না করেই -lstdc++fsআমি একটি পেয়েছি SIGSEGV (Address boundary error)। এটি প্রয়োজনীয় যে ডকুমেন্টেশনে আমি কোথাও খুঁজে পাইনি এবং লিঙ্কার কোনও চিহ্নই দেয়নি। এটি উভয়ের পক্ষে কাজ করেছিল g++ 8.3.0এবং clang 8.0.0-3। কারও কি কোনও অন্তর্দৃষ্টি আছে যেখানে ডক্স / স্পেসে এই জাতীয় জিনিস নির্দিষ্ট করা আছে?
সোয়াগল

229

দুর্ভাগ্যক্রমে সি ++ স্ট্যান্ডার্ড এইভাবে ফাইল এবং ফোল্ডারগুলির সাথে কাজ করার একটি মানক উপায়টিকে সংজ্ঞায়িত করে না।

যেহেতু কোনও ক্রস প্ল্যাটফর্মের উপায় নেই, সর্বোত্তম ক্রস প্ল্যাটফর্মের উপায় হ'ল বুস্ট ফাইল সিস্টেম মডিউলটির মতো লাইব্রেরি ব্যবহার করা ।

ক্রস প্ল্যাটফর্ম বুস্ট পদ্ধতি:

ডিরেক্টরি ফাংশন এবং একটি ফাইলের নাম প্রদত্ত নিম্নলিখিত ফাংশনটি পুনরাবৃত্তভাবে ফাইল নামের জন্য ডিরেক্টরি এবং এর উপ ডিরেক্টরিগুলি অনুসন্ধান করে, একটি বিল ফিরিয়ে দেয় এবং যদি সফল হয়, তবে ফাইলটি খুঁজে পাওয়া যায়।

bool find_file(const path & dir_path,         // in this directory,
               const std::string & file_name, // search for this name,
               path & path_found)             // placing path here if found
{
    if (!exists(dir_path)) 
        return false;

    directory_iterator end_itr; // default construction yields past-the-end

    for (directory_iterator itr(dir_path); itr != end_itr; ++itr)
    {
        if (is_directory(itr->status()))
        {
            if (find_file(itr->path(), file_name, path_found)) 
                return true;
        }
        else if (itr->leaf() == file_name) // see below
        {
            path_found = itr->path();
            return true;
        }
    }
    return false;
}

উপরে উল্লিখিত বুস্ট পৃষ্ঠা থেকে উত্স।

ইউনিক্স / লিনাক্স ভিত্তিক সিস্টেমগুলির জন্য:

আপনি ব্যবহার করতে পারেন opendir / দ্বারা readdir / closedir

Entry `নাম '' এন্ট্রি করার জন্য একটি ডিরেক্টরি অনুসন্ধান করে এমন নমুনা কোডটি হ'ল:

len = strlen(name);
dirp = opendir(".");
while ((dp = readdir(dirp)) != NULL)
        if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
                (void)closedir(dirp);
                return FOUND;
        }
(void)closedir(dirp);
return NOT_FOUND;

উপরের ম্যান পৃষ্ঠাগুলি থেকে উত্স কোড।

উইন্ডোজ ভিত্তিক সিস্টেমগুলির জন্য:

আপনি উইন 32 এপিআই ফাইন্ডফারস্টফিল / ফাইন্ডনেক্সটফিল / ফাইন্ডক্লোজ ফাংশন ব্যবহার করতে পারেন ।

নিম্নলিখিত সি ++ উদাহরণ আপনাকে ফাইন্ডফার্সফায়ালের ন্যূনতম ব্যবহার দেখায়।

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

void _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Target file is %s\n"), argv[1]);
   hFind = FindFirstFile(argv[1], &FindFileData);
   if (hFind == INVALID_HANDLE_VALUE) 
   {
      printf ("FindFirstFile failed (%d)\n", GetLastError());
      return;
   } 
   else 
   {
      _tprintf (TEXT("The first file found is %s\n"), 
                FindFileData.cFileName);
      FindClose(hFind);
   }
}

উপরের এমএসডিএন পৃষ্ঠা থেকে উত্স কোড।


ব্যবহার:FindFirstFile(TEXT("D:\\IMAGE\\MYDIRECTORY\\*"), &findFileData);
Ван

7
সি ++ ১৪ এর std::experimental::filesystemসাথে সি ++ 17 রয়েছে std::filesystem, যার বুস্টের মতো কার্যকারিতা রয়েছে (লিবগুলি বুস্ট থেকে প্রাপ্ত)। নীচে শ্রীবর্ধনের উত্তর দেখুন।
ড্যান্টন


90

একটি ফাংশনই যথেষ্ট, আপনার কোনও তৃতীয় পক্ষের লাইব্রেরি (উইন্ডোজের জন্য) ব্যবহার করার দরকার নেই।

#include <Windows.h>

vector<string> get_all_files_names_within_folder(string folder)
{
    vector<string> names;
    string search_path = folder + "/*.*";
    WIN32_FIND_DATA fd; 
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); 
    if(hFind != INVALID_HANDLE_VALUE) { 
        do { 
            // read all (real) files in current folder
            // , delete '!' read other 2 default folder . and ..
            if(! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
                names.push_back(fd.cFileName);
            }
        }while(::FindNextFile(hFind, &fd)); 
        ::FindClose(hFind); 
    } 
    return names;
}

দ্রষ্টব্য: যেমন @Sebastian উল্লেখ, আপনি পরিবর্তন হতে পারে *.*থেকে *.extঅর্ডার শুধুমাত্র EXT-ফাইল পেতে (ক নির্দিষ্ট ধরণের অর্থাত) যে ডিরেক্টরির মধ্যে হবে।


20
প্ল্যাটফর্ম নির্দিষ্ট এই সমাধান। এজন্য আপনার তৃতীয় পক্ষের লাইব্রেরি প্রয়োজন।
kraxor

9
@ ক্র্যাক্সর হ্যাঁ, এটি কেবল উইন্ডোজেই কাজ করে তবে ওপি কখনও ক্রস-প্ল্যাটফর্ম সমাধান করতে বলে না। বিটিডাব্লু, আমি সর্বদা তৃতীয়-গ্রন্থাগার (যদি সম্ভব হয়) না ব্যবহার করে কিছু পছন্দ করতে পছন্দ করি।
নায়কহিয়ংটাও

7
@ হ্যারোহ্যুংটাও ওপি কখনই কোনও প্ল্যাটফর্ম নির্দিষ্ট করেনি এবং জেনেরিক প্রশ্নের একটি ভারী প্ল্যাটফর্ম নির্ভর নির্ভর সমাধান দেওয়া বিভ্রান্তিকর হতে পারে। (যদি কেবল কোনও প্লেস্টেশন 3-তে কাজ করে এমন এক-লাইন সমাধান হয় তবে কী এটি এখানে একটি ভাল উত্তর?) আমি আপনাকে আপনার উত্তরটি সম্পাদন করতে দেখলাম যে এটি কেবল উইন্ডোজে কাজ করে, আমি অনুমান করি যে এটি ঠিক আছে।
kraxor

1
@ হ্যারোহ্যুংটাও ওপি উল্লেখ করেছেন যে তিনি এলএস পার্স করতে পারবেন না, যার অর্থ তিনি সম্ভবত ইউনিক্সে রয়েছেন .. যাইহোক, উইন্ডোজের পক্ষে ভাল উত্তর।
থমাস

2
আমি স্ট্রিংগুলির একটি ভেক্টরের পরিবর্তে একটি std::vector<std::wstring>এবং তারপরে ব্যবহার করে শেষ করেছি fileName.c_str()যা সংকলন করবে না।
পেরিসি

51

কেবলমাত্র সি-র সমাধানের জন্য, এটি পরীক্ষা করে দেখুন। এটির জন্য কেবল অতিরিক্ত শিরোনাম প্রয়োজন:

https://github.com/cxong/tinydir

tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");

while (dir.has_next)
{
    tinydir_file file;
    tinydir_readfile(&dir, &file);

    printf("%s", file.name);
    if (file.is_dir)
    {
        printf("/");
    }
    printf("\n");

    tinydir_next(&dir);
}

tinydir_close(&dir);

অন্যান্য বিকল্পের তুলনায় কিছু সুবিধা:

  • এটি পোর্টেবল - পসিক্স ডাইরেক্ট এবং উইন্ডোজ ফাইন্ডফার্সফাইলে মোড়ানো
  • এটি readdir_rযেখানে উপলব্ধ সেখানে এটি ব্যবহার করে যার অর্থ এটি (সাধারণত) থ্রেডসেফ
  • একই UNICODEম্যাক্রোগুলির মাধ্যমে উইন্ডোজ ইউটিএফ -16 সমর্থন করে
  • এটি সি 90 তাই খুব প্রাচীন সংকলকরা এটি ব্যবহার করতে পারে

2
খুব সুন্দর পরামর্শ। আমি জানালা কম্পিউটারের তে এটি পরীক্ষিত এখনো হয়নি কিন্তু এটা OS X এর উপর বুদ্ধিদীপ্তভাবে কাজ করে
ArtOfWarfare

লাইব্রেরিটি std :: স্ট্রিং সমর্থন করে না, সুতরাং আপনি ফাইল cd_str () tinydir_open এ পাস করতে পারবেন না। এই ক্ষেত্রে এমএসভিসি 2015-তে সংকলনের সময় এটি ত্রুটি C2664 দেয়।
স্টেপান ইয়াকোভেনকো

33

আমি globএই পুনরায় ব্যবহারযোগ্য মোড়ক ব্যবহার করার পরামর্শ দিচ্ছি । এটি vector<string>বিশ্বব্যাপী প্যাটার্নের সাথে খাপ খায় এমন ফাইলের সাথে সম্পর্কিত করে:

#include <glob.h>
#include <vector>
using std::vector;

vector<string> globVector(const string& pattern){
    glob_t glob_result;
    glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
    vector<string> files;
    for(unsigned int i=0;i<glob_result.gl_pathc;++i){
        files.push_back(string(glob_result.gl_pathv[i]));
    }
    globfree(&glob_result);
    return files;
}

যা তখন সাধারণ সিস্টেমের ওয়াইল্ডকার্ড প্যাটার্ন সহ যেমন বলা যেতে পারে:

vector<string> files = globVector("./*");

2
পরীক্ষা করুন যে গ্লোব () শূন্য প্রত্যাবর্তন করে।
ক্যামিল গৌডেসুন 21'15

আপনার সুপারিশ অনুসারে আমি glob.h ব্যবহার করতে চাই। কিন্তু এখনও, আমি জ ফাইল অন্তর্ভুক্ত করতে পারে না: এরা বলছে No such file or directory। আপনি কীভাবে আমাকে এই সমস্যাটি সমাধান করবেন তা বলতে পারেন?
তোফু

নোট করুন যে এই রুটিনটি কেবলমাত্র এক স্তর গভীর (কোনও পুনরাবৃত্তি নয়)। এটি একটি দ্রুত চেক কিনা তা নির্ধারণ করতে এটি একটি ফাইল অথবা ডাইরেক্টরি, যা আপনি সুইচিং দ্বারা সহজেই করতে পারেন করে না GLOB_TILDEসঙ্গে GLOB_TILDE | GLOB_MARKএবং তারপর একটি স্ল্যাশ শেষ হওয়া পাথ পরীক্ষা করার। আপনার যদি এটির প্রয়োজন হয় তবে আপনাকে এটিতে কোনও পরিবর্তন করতে হবে।
ভলমাইক

এই ক্রস প্ল্যাটফর্মটি কি সামঞ্জস্যপূর্ণ?
নিখিল অগাস্টিন

দুর্ভাগ্যক্রমে আপনি এর মাধ্যমে অভিন্ন লুকানো ফাইলগুলি খুঁজে পাবেন না glob
এলএমটিনিটুন

23

ডিরেক্টরিতে ফাইলের নাম (ফোল্ডারের নাম বাদে) পাওয়ার জন্য লাইব্রেরিটি C++11ব্যবহার boost::filesystemকরার জন্য এখানে একটি খুব সহজ কোড রয়েছে :

#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

int main()
{
    path p("D:/AnyFolder");
    for (auto i = directory_iterator(p); i != directory_iterator(); i++)
    {
        if (!is_directory(i->path())) //we eliminate directories
        {
            cout << i->path().filename().string() << endl;
        }
        else
            continue;
    }
}

আউটপুট যেমন:

file1.txt
file2.dat

হাই, এবং আমি এই লাইব্রেরিটি কোথায় পেতে পারি?
আলেকজান্ডার লিওন ষষ্ঠ

2
@ আলেকজান্ডার ডি লিওন: আপনি এই লাইব্রেরিটি তাদের সাইটে boost.org এ পেতে পারেন , প্রথমে গাইডিং শুরু করতে পড়তে পারেন, তারপরে তাদের boost::filesystemলাইব্রেরি boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm
খারাপ

23

কেন ব্যবহার glob()করবেন না ?

#include <glob.h>

glob_t glob_result;
glob("/your_directory/*",GLOB_TILDE,NULL,&glob_result);
for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
  cout << glob_result.gl_pathv[i] << endl;
}

আপনি যদি প্রয়োজনীয় অন্তর্ভুক্তগুলি ব্যাখ্যা করেন তবে এটি আরও ভাল উত্তর হতে পারে।
ভলমাইক

2
পরীক্ষা যে গ্লোব () শূন্য!
অরবিটকবোয়

আপনি যখন ফাইলটি সন্ধান করছেন তা জানেন তখন ভাল হয় * .txt
কেমিন ঝো

20

আমি মনে করি, নীচে স্নিপেট সমস্ত ফাইলের তালিকাতে ব্যবহার করা যেতে পারে।

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>

static void list_dir(const char *path)
{
    struct dirent *entry;
    DIR *dir = opendir(path);
    if (dir == NULL) {
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n",entry->d_name);
    }

    closedir(dir);
}

নীচে স্ট্রাক্ট নির্দেশের কাঠামোটি দেওয়া হল

struct dirent {
    ino_t d_ino; /* inode number */
    off_t d_off; /* offset to the next dirent */
    unsigned short d_reclen; /* length of this record */
    unsigned char d_type; /* type of file */
    char d_name[256]; /* filename */
};

আমি এই এক চাই।
সেলফুট বুধ

10

এক্স-প্ল্যাটফর্ম পদ্ধতির জন্য বুস্ট করার চেষ্টা করুন

http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm

বা কেবল আপনার ওএস নির্দিষ্ট ফাইল স্টাফ ব্যবহার করুন।


যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত পৃষ্ঠাগুলি পরিবর্তিত হলে লিঙ্ক-শুধুমাত্র উত্তরগুলি অবৈধ হতে পারে। - পর্যালোচনা থেকে
આઇસ 1000

@ আইস 1000 সিরিয়াসলি? এই প্রশ্নোত্তরটি 2009
টিম

8

এই ক্লাসটি যা win32 এপিআই ব্যবহার করে দেখুন। foldernameআপনি যে তালিকাটি চান তা সরবরাহ করে কেবল একটি উদাহরণ তৈরি করুন এবং তারপরে ডিরেক্টরি থেকে getNextFileপরবর্তীটি filenameপাওয়ার জন্য পদ্ধতিটি কল করুন । আমি মনে করি এটি প্রয়োজন windows.hএবং stdio.h

class FileGetter{
    WIN32_FIND_DATAA found; 
    HANDLE hfind;
    char folderstar[255];       
    int chk;

public:
    FileGetter(char* folder){       
        sprintf(folderstar,"%s\\*.*",folder);
        hfind = FindFirstFileA(folderstar,&found);
        //skip .
        FindNextFileA(hfind,&found);        
    }

    int getNextFile(char* fname){
        //skips .. when called for the first time
        chk=FindNextFileA(hfind,&found);
        if (chk)
            strcpy(fname, found.cFileName);     
        return chk;
    }

};

6

জিএনইউ ম্যানুয়াল এফটিডাব্লু

http://www.gnu.org/software/libc/manual/html_node/Simple-Directory-Lister.html#Simple-Directory-Lister

এছাড়াও, কখনও কখনও উত্স থেকে ডান যেতে ভাল (পাং উদ্দেশ্যে)। লিনাক্সের কয়েকটি সাধারণ কমান্ডের অভ্যন্তরীণ অংশগুলি দেখে আপনি অনেক কিছু শিখতে পারেন। আমি গিথুবে (পড়ার জন্য) জিএনইউর কোরিউটিলসের একটি সাধারণ আয়না স্থাপন করেছি।

https://github.com/homer6/gnu_coreutils/blob/master/src/ls.c

সম্ভবত এটি উইন্ডোজকে সম্বোধন করে না, তবে ইউনিক্স রূপগুলি ব্যবহারের কয়েকটি ক্ষেত্রে এই পদ্ধতিগুলি ব্যবহার করে দেখা যেতে পারে।

আশা করি এইটি কাজ করবে...


5

শ্রীবর্ধন উত্তর দুর্দান্ত কাজ করে। তবে আপনি যদি এটি সি ++ 14 এ ব্যবহার করতে চান তবে কেবল একটি পরিবর্তন করুনnamespace fs = experimental::filesystem;

অর্থাত,

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

using namespace std;
namespace fs = experimental::filesystem;

int main()
{
    string path = "C:\\splits\\";
    for (auto & p : fs::directory_iterator(path))
        cout << p << endl;
    int n;
    cin >> n;
}

4
char **getKeys(char *data_dir, char* tablename, int *num_keys)
{
    char** arr = malloc(MAX_RECORDS_PER_TABLE*sizeof(char*));
int i = 0;
for (;i < MAX_RECORDS_PER_TABLE; i++)
    arr[i] = malloc( (MAX_KEY_LEN+1) * sizeof(char) );  


char *buf = (char *)malloc( (MAX_KEY_LEN+1)*sizeof(char) );
snprintf(buf, MAX_KEY_LEN+1, "%s/%s", data_dir, tablename);

DIR* tableDir = opendir(buf);
struct dirent* getInfo;

readdir(tableDir); // ignore '.'
readdir(tableDir); // ignore '..'

i = 0;
while(1)
{


    getInfo = readdir(tableDir);
    if (getInfo == 0)
        break;
    strcpy(arr[i++], getInfo->d_name);
}
*(num_keys) = i;
return arr;
}

3

আমি আশা করি এই কোডটি আপনাকে সহায়তা করবে।

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

string wchar_t2string(const wchar_t *wchar)
{
    string str = "";
    int index = 0;
    while(wchar[index] != 0)
    {
        str += (char)wchar[index];
        ++index;
    }
    return str;
}

wchar_t *string2wchar_t(const string &str)
{
    wchar_t wchar[260];
    int index = 0;
    while(index < str.size())
    {
        wchar[index] = (wchar_t)str[index];
        ++index;
    }
    wchar[index] = 0;
    return wchar;
}

vector<string> listFilesInDirectory(string directoryName)
{
    WIN32_FIND_DATA FindFileData;
    wchar_t * FileName = string2wchar_t(directoryName);
    HANDLE hFind = FindFirstFile(FileName, &FindFileData);

    vector<string> listFileNames;
    listFileNames.push_back(wchar_t2string(FindFileData.cFileName));

    while (FindNextFile(hFind, &FindFileData))
        listFileNames.push_back(wchar_t2string(FindFileData.cFileName));

    return listFileNames;
}

void main()
{
    vector<string> listFiles;
    listFiles = listFilesInDirectory("C:\\*.txt");
    for each (string str in listFiles)
        cout << str << endl;
}

4
-1। string2wchar_tস্থানীয় ভেরিয়েবলের ঠিকানা প্রদান করে। এছাড়াও, আপনার নিজের নিজের লেখার পরিবর্তে আপনার সম্ভবত উইনাপিতে উপলব্ধ রূপান্তর পদ্ধতিগুলি ব্যবহার করা উচিত।
ড্যানিয়েল কামিল কোজার

3

এই প্রয়োগটি আপনার উদ্দেশ্যকে উপলব্ধি করে, নির্দিষ্ট ডিরেক্টরিটির বিষয়বস্তু দিয়ে গতিশীলভাবে একটি স্ট্রিংয়ের অ্যারে পূরণ করে।

int exploreDirectory(const char *dirpath, char ***list, int *numItems) {
    struct dirent **direntList;
    int i;
    errno = 0;

    if ((*numItems = scandir(dirpath, &direntList, NULL, alphasort)) == -1)
        return errno;

    if (!((*list) = malloc(sizeof(char *) * (*numItems)))) {
        fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < *numItems; i++) {
        (*list)[i] = stringDuplication(direntList[i]->d_name);
    }

    for (i = 0; i < *numItems; i++) {
        free(direntList[i]);
    }

    free(direntList);

    return 0;
}

আমি এটিকে কীভাবে ডাকব? আমি প্রথম ifব্লকে এই ফাংশনটি চালানোর চেষ্টা করার সময় আমি সেগফোল্টস পাচ্ছি । আমি এটির সাথে কল করছিchar **list; int numItems; exploreDirectory("/folder",list, numItems);
হাল টি টি

2

এটি আমার পক্ষে কাজ করে। আমি যদি উত্সটি মনে করতে না পারি তবে আমি দুঃখিত। এটি সম্ভবত কোনও ম্যান পেজ থেকে।

#include <ftw.h>

int AnalizeDirectoryElement (const char *fpath, 
                            const struct stat *sb,
                            int tflag, 
                            struct FTW *ftwbuf) {

  if (tflag == FTW_F) {
    std::string strFileName(fpath);

    DoSomethingWith(strFileName);
  }
  return 0; 
}

void WalkDirectoryTree (const char * pchFileName) {

  int nFlags = 0;

  if (nftw(pchFileName, AnalizeDirectoryElement, 20, nFlags) == -1) {
    perror("nftw");
  }
}

int main() {
  WalkDirectoryTree("some_dir/");
}

2

আপনি আপনার রুট ডিরেক্টরিতে সমস্ত স্টাইড ফাইল সরাসরি স্ট্রাইড :: পরীক্ষামূলক :: ফাইলসিসট :: ডিরেক্টরি_iterator () ব্যবহার করে পেতে পারেন। তারপরে, এই পাথফিলগুলির নামটি পড়ুন।

#include <iostream>
#include <filesystem>
#include <string>
#include <direct.h>
using namespace std;
namespace fs = std::experimental::filesystem;
void ShowListFile(string path)
{
for(auto &p: fs::directory_iterator(path))  /*get directory */
     cout<<p.path().filename()<<endl;   // get file name
}

int main() {

ShowListFile("C:/Users/dell/Pictures/Camera Roll/");
getchar();
return 0;
}

2

এই উত্তরটি উইন্ডোজ ব্যবহারকারীদের জন্য কাজ করা উচিত যা অন্য যে কোনও উত্তরের সাথে ভিজ্যুয়াল স্টুডিওতে এই কাজ করতে সমস্যা হয়েছিল।

  1. গিথুব পৃষ্ঠা থেকে ডিরেক্টরি ডাউনলোড করুন .h তবে কেবলমাত্র র ডাইরেন্ট ড। ফাইলটি ব্যবহার করা এবং নীচে আমার পদক্ষেপগুলি অনুসরণ করা ভাল (এটি আমি এটি কাজ করতে পেলাম)।

    উইন্ডোজের জন্য গিথুব পৃষ্ঠা : উইন্ডোজের জন্য গিথুব পৃষ্ঠা

    কাঁচা ডাইরেন্ট ফাইল: কাঁচা ডাইরেন্ট। ফাইল

  2. আপনার প্রকল্পে যান এবং একটি নতুন আইটেম যুক্ত করুন ( Ctrl+ Shift+ A)। একটি শিরোলেখ ফাইল (.h) যুক্ত করুন এবং এটি নাম ডিরেক্টরি দিন।

  3. আপনার শিরোনামে কাঁচা নির্দেশক। ফাইল কোড আটকান ।

  4. আপনার কোডে "ডিরেক্টরি" র অন্তর্ভুক্ত করুন।

  5. নীচের void filefinder()পদ্ধতিটি আপনার কোডটিতে রাখুন এবং এটি আপনার mainফাংশন থেকে কল করুন বা আপনি কীভাবে এটি ব্যবহার করতে চান তা ফাংশনটি সম্পাদনা করুন।

    #include <stdio.h>
    #include <string.h>
    #include "dirent.h"
    
    string path = "C:/folder"; //Put a valid path here for folder
    
    void filefinder()
    {
        DIR *directory = opendir(path.c_str());
        struct dirent *direntStruct;
    
        if (directory != NULL) {
            while (direntStruct = readdir(directory)) {
                printf("File Name: %s\n", direntStruct->d_name); //If you are using <stdio.h>
                //std::cout << direntStruct->d_name << std::endl; //If you are using <iostream>
            }
        }
        closedir(directory);
    }

1

সিস্টেম এটি কল!

system( "dir /b /s /a-d * > file_names.txt" );

তারপরে কেবল ফাইলটি পড়ুন।

সম্পাদনা: এই উত্তরটিকে হ্যাক হিসাবে বিবেচনা করা উচিত, তবে যদি আপনার আরও মার্জিত সমাধানগুলিতে অ্যাক্সেস না থাকে তবে এটি সত্যিই কার্যকর হয় (প্ল্যাটফর্মের নির্দিষ্ট উপায়ে হলেও) does


7
আমাকে 'ls' কমান্ড কার্যকর করতে এবং আমার প্রোগ্রামের মধ্যে থেকে ফলাফলগুলি পার্স করার অনুমতি নেই। আমি জানতাম এমন কেউ আছেন যে এই জাতীয় কিছু পাঠিয়ে দেবে ...
yyny

1

যেহেতু ডিরেক্টরিগুলির ফাইল এবং উপ ডিরেক্টরিগুলি সাধারণত একটি কাঠের কাঠামোর মধ্যে সংরক্ষণ করা হয়, তাই একটি স্বজ্ঞাত উপায় হ'ল ডিএফএস অ্যালগরিদম ব্যবহার করে তাদের প্রতিটিকে পুনরাবৃত্তভাবে অনুসরণ করতে। এখানে উইন্ডোজ অপারেটিং সিস্টেমের একটি উদাহরণ আইও এইচ। তে বেসিক ফাইল ফাংশন ব্যবহার করে is আপনি অন্য প্ল্যাটফর্মে এই ফাংশনগুলি প্রতিস্থাপন করতে পারেন। আমি যা প্রকাশ করতে চাই তা হ'ল ডিএফএসের প্রাথমিক ধারণাটি পুরোপুরি এই সমস্যার সাথে মেলে।

#include<io.h>
#include<iostream.h>
#include<string>
using namespace std;

void TraverseFilesUsingDFS(const string& folder_path){
   _finddata_t file_info;
   string any_file_pattern = folder_path + "\\*";
   intptr_t handle = _findfirst(any_file_pattern.c_str(),&file_info);
   //If folder_path exsist, using any_file_pattern will find at least two files "." and "..", 
   //of which "." means current dir and ".." means parent dir
   if (handle == -1){
       cerr << "folder path not exist: " << folder_path << endl;
       exit(-1);
   }
   //iteratively check each file or sub_directory in current folder
   do{
       string file_name=file_info.name; //from char array to string
       //check whtether it is a sub direcotry or a file
       if (file_info.attrib & _A_SUBDIR){
            if (file_name != "." && file_name != ".."){
               string sub_folder_path = folder_path + "\\" + file_name;                
               TraverseFilesUsingDFS(sub_folder_path);
               cout << "a sub_folder path: " << sub_folder_path << endl;
            }
       }
       else
            cout << "file name: " << file_name << endl;
    } while (_findnext(handle, &file_info) == 0);
    //
    _findclose(handle);
}

1

আমি উভয় উত্তরে প্রদত্ত উদাহরণটি অনুসরণ করার চেষ্টা করেছি এবং এটি লক্ষণীয় যে এটি প্রদর্শিত হবে যেন অপারেটরের std::filesystem::directory_entryওভারলোড না পেয়ে পরিবর্তন করা হয়েছে <<। এর পরিবর্তে std::cout << p << std::endl;আমাকে সংকলন করতে এবং এটি কাজ করতে সক্ষম হতে নিম্নলিখিতগুলি ব্যবহার করতে হয়েছিল:

#include <iostream>
#include <filesystem>
#include <string>
namespace fs = std::filesystem;

int main() {
    std::string path = "/path/to/directory";
    for(const auto& p : fs::directory_iterator(path))
        std::cout << p.path() << std::endl;
}

হারিয়ে যাওয়ার ওভারলোডের ত্রুটির ফলে pএটি নিজেই পাস করার চেষ্টা করা হচ্ছে std::cout <<


1

হিরহিউংটাও কী পোস্ট করেছে এবং আরও কয়েকটি পোস্ট তৈরি করছে:

http://www.cplusplus.com/forum/general/39766/

ফাইন্ডফার্সফাইলে প্রত্যাশিত ইনপুট ধরণটি কী?

Wstring কে স্ট্রিংয়ে রূপান্তর করবেন?

এটি একটি উইন্ডোজ সমাধান।

যেহেতু আমি স্টাড :: স্ট্রিংয়ে পাস এবং স্ট্রিংয়ের একটি ভেক্টর ফিরে আসতে চেয়েছিলাম আমাকে কয়েকটা রূপান্তর করতে হয়েছিল।

#include <string>
#include <Windows.h>
#include <vector>
#include <locale>
#include <codecvt>

std::vector<std::string> listFilesInDir(std::string path)
{
    std::vector<std::string> names;
    //Convert string to wstring
    std::wstring search_path = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(path);
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile(search_path.c_str(), &fd);
    if (hFind != INVALID_HANDLE_VALUE) 
    {
        do 
        {
            // read all (real) files in current folder
            // , delete '!' read other 2 default folder . and ..
            if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
            {
                //convert from wide char to narrow char array
                char ch[260];
                char DefChar = ' ';
                WideCharToMultiByte(CP_ACP, 0, fd.cFileName, -1, ch, 260, &DefChar, NULL);
                names.push_back(ch);
            }
        } 
        while (::FindNextFile(hFind, &fd));
        ::FindClose(hFind);
    }
    return names;
}

আপনি কি জানেন multibyte ব্যবহার আপনি শুধুমাত্র করা হবে ব্যবহার করতে পারে WIN32_FIND_DATAA, FindFirstFileAএবং FindNextFileA। তারপরে ফলটিকে মাল্টবাইট বা ইনপুটকে ইউনিকোডে রূপান্তর করার প্রয়োজন হবে না।
কিরণ থিলাক

0

আমি পাঠ্য উপাদানের জন্য যা কিছু ভাগ করতে এবং ধন্যবাদ জানাতে চাই। কিছুটা বুঝতে এটি ফাংশনটি নিয়ে চারপাশে খেলুন। আপনি এটি পছন্দ করতে পারেন। e এক্সটেনশনের জন্য দাঁড়িয়েছিল, পি পথের জন্য এবং এস পথ বিভাজকের জন্য।

বিভাজক শেষ না করেই যদি পথটি পাস করা হয় তবে একটি বিভাজক পথটিতে সংযুক্ত হবে। এক্সটেনশনের জন্য, যদি খালি স্ট্রিংটি ইনপুট করা থাকে তবে ফাংশনটি এমন কোনও ফাইলকে ফিরিয়ে দেবে যার নামে কোনও এক্সটেনশন নেই। ডিরেক্টরিতে থাকা সমস্ত ফাইলের চেয়ে যদি কোনও একক তারকাকে ইনপুট করা হয় তবে তা ফিরে আসবে। যদি ই দৈর্ঘ্য 0 এর চেয়ে বেশি হয় তবে একক না হয় * তবে শটে শূন্য অবস্থানে বিন্দু না থাকলে ই-তে একটি বিন্দু প্রেরণ করা হবে।

একটি ফেরতের মান জন্য। যদি শূন্য-দৈর্ঘ্যের মানচিত্রটি ফিরে আসে তবে ডিরেক্টরিটি ঠিক আছে, তবে কিছুই পাওয়া গেল না। যদি সূচক 999 যদি ফেরতের মান থেকে পাওয়া যায় তবে মানচিত্রের আকারটি কেবল 1 তবে তার অর্থ ডিরেক্টরি পথটি খোলার ক্ষেত্রে সমস্যা ছিল।

মনে রাখবেন দক্ষতার জন্য, এই ফাংশনটি 3 টি ছোট ফাংশনে বিভক্ত করা যেতে পারে। তার উপরে, আপনি একটি কলার ফাংশন তৈরি করতে পারেন যা সনাক্ত করবে যে এটি কোন ফাংশনটি ইনপুটটির উপর ভিত্তি করে কল করতে চলেছে। কেন যে আরও দক্ষ? বলেছিলেন যে আপনি যদি ফাইলের মতো সমস্ত কিছু দখল করতে চলেছেন, সেই পদ্ধতিটি সম্পাদন করে সমস্ত ফাইল যে সমস্ত ফাইল দখল করার জন্য তৈরি হয়েছিল তা কেবল ফাইলগুলিই দখল করবে এবং প্রতিবার কোনও ফাইল খুঁজে পাওয়ার সাথে সাথে অন্য কোনও অপ্রয়োজনীয় অবস্থার মূল্যায়ন করার প্রয়োজন নেই।

আপনি যখন এক্সটেনশন না থাকা ফাইলগুলি দখল করেন তখন এটিও প্রযোজ্য। এই উদ্দেশ্যে একটি নির্দিষ্ট বিল্ট ফাংশন কেবলমাত্র আবহাওয়ার জন্য মূল্যায়ন করবে যদি প্রাপ্ত বস্তুটি কোনও ফাইল হয় এবং তারপরে ফাইলটির নামটিতে কোনও বিন্দু আছে কি না।

আপনি কেবলমাত্র এতগুলি ফাইল না দিয়ে ডিরেক্টরিগুলি পড়েন তবে সঞ্চয়টি খুব বেশি নাও হতে পারে। তবে আপনি যদি প্রচুর পরিমাণে ডিরেক্টরি পড়ছেন বা ডিরেক্টরিতে কয়েক লক্ষ ফাইল রয়েছে তবে এটি একটি বিশাল সঞ্চয় হতে পারে।

#include <stdio.h>
#include <sys/stat.h>
#include <iostream>
#include <dirent.h>
#include <map>

std::map<int, std::string> getFile(std::string p, std::string e = "", unsigned char s = '/'){
    if ( p.size() > 0 ){
        if (p.back() != s) p += s;
    }
    if ( e.size() > 0 ){
        if ( e.at(0) != '.' && !(e.size() == 1 && e.at(0) == '*') ) e = "." + e;
    }

    DIR *dir;
    struct dirent *ent;
    struct stat sb;
    std::map<int, std::string> r = {{999, "FAILED"}};
    std::string temp;
    int f = 0;
    bool fd;

    if ( (dir = opendir(p.c_str())) != NULL ){
        r.erase (999);
        while ((ent = readdir (dir)) != NULL){
            temp = ent->d_name;
            fd = temp.find(".") != std::string::npos? true : false;
            temp = p + temp;

            if (stat(temp.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)){
                if ( e.size() == 1 && e.at(0) == '*' ){
                    r[f] = temp;
                    f++;
                } else {
                    if (e.size() == 0){
                        if ( fd == false ){
                            r[f] = temp;
                            f++;
                        }
                        continue;
                    }

                    if (e.size() > temp.size()) continue;

                    if ( temp.substr(temp.size() - e.size()) == e ){
                        r[f] = temp;
                        f++;
                    }
                }
            }
        }

        closedir(dir);
        return r;
    } else {
        return r;
    }
}

void printMap(auto &m){
    for (const auto &p : m) {
        std::cout << "m[" << p.first << "] = " << p.second << std::endl;
    }
}

int main(){
    std::map<int, std::string> k = getFile("./", "");
    printMap(k);
    return 0;
}

0
#include<iostream>
#include <dirent.h>
using namespace std;
char ROOT[]={'.'};

void listfiles(char* path){
    DIR * dirp = opendir(path);
    dirent * dp;
    while ( (dp = readdir(dirp)) !=NULL ) {
         cout << dp->d_name << " size " << dp->d_reclen<<std::endl;
    }
    (void)closedir(dirp);
}

int main(int argc, char **argv)
{
    char* path;
    if (argc>1) path=argv[1]; else path=ROOT;

    cout<<"list files in ["<<path<<"]"<<std::endl;
    listfiles(path);

    return 0;
}

-1

এটি আমার পক্ষে কাজ করেছে। এটি সমস্ত ফাইলের নাম (কোনও পথ নেই) দিয়ে একটি ফাইল লিখে দেয়। তারপরে এটি সেই টেক্সট ফাইলটি পড়ে এবং এটি আপনার জন্য মুদ্রণ করে।

void DisplayFolderContent()
    {

        system("dir /n /b * > file_names.txt");
        char ch;
        std::fstream myStream("file_names.txt", std::fstream::in);
        while (myStream.get(ch))
        {
            std::cout << ch;
        }

    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.