आप हर फ़ाइल / निर्देशिका के माध्यम से पुनरावृत्ति कैसे मानक C ++ में करते हैं?


115

आप हर फ़ाइल / निर्देशिका के माध्यम से पुनरावृत्ति कैसे मानक C ++ में करते हैं?


आप boost.filesystem जांच करने के लिए चाहते हो सकता है boost.org/doc/libs/1_31_0/libs/filesystem/doc/index.htm
डौग टी


1
यह जल्द ही फाइलसिस्टम टीएस के माध्यम से मानक में होना चाहिए , पुनरावर्ती_निदेशक_लेखक के
आदि शाविट

यदि मानक C लाइब्रेरी का उपयोग C ++ प्रोग्राम को 'मानक', nftw () के रूप में कॉल करने के तरीके से नहीं होता है । यहाँ एक व्यावहारिक उदाहरण है
छह-कश्मीर

2
कोई, जो जानता है कि वे क्या कर रहे हैं, इसे अपडेट करने के लिए एक घंटे का समय चाहिए।
जोश सी

जवाबों:


99

मानक C ++ में, तकनीकी रूप से ऐसा करने का कोई तरीका नहीं है क्योंकि मानक C ++ में निर्देशिकाओं की कोई अवधारणा नहीं है। यदि आप अपने नेट का थोड़ा विस्तार करना चाहते हैं, तो आप Boost.FileSystem का उपयोग करना पसंद कर सकते हैं । यह TR2 में शामिल करने के लिए स्वीकार किया गया है, इसलिए यह आपको अपने कार्यान्वयन को मानक के जितना संभव हो सके रखने का सबसे अच्छा मौका देता है।

एक उदाहरण, वेबसाइट से सीधे लिया गया:

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;
}

5
C ++ में फ़ाइलों की कोई अवधारणा नहीं है? Std :: fstream के बारे में क्या? या फोपेन?
केविन

30
फाइलें, निर्देशिका नहीं
1800 सूचना

22
नवीनतम बूस्ट संस्करण के संबंध में अपडेट करें: यदि कोई भी इस उत्तर में ठोकर खाता है, तो नवीनतम बढ़ावा में एक सुविधा वर्ग को बढ़ावा देना शामिल है :: recursive_directory_iterator इसलिए स्पष्ट पुनरावर्ती कॉल के साथ उपरोक्त लूप लिखना अब आवश्यक नहीं है। लिंक: boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/…
जसदेव

5
VC ++ 11 std :: tr2 :: sys namespace के अंतर्गत <filesystem> शीर्ष लेख में समान कार्यक्षमता के साथ आता है।
माहेमान

3
यह एक अच्छा उत्तर हुआ करता था, लेकिन अब जब <filesystem> मानक है, तो बस उपयोग करना बेहतर है (उदाहरण के लिए अन्य उत्तर देखें)।
गतधर

54

C ++ 17 से आगे, <filesystem>हेडर और रेंज- से for, आप बस ऐसा कर सकते हैं:

#include <filesystem>

using recursive_directory_iterator = std::filesystem::recursive_directory_iterator;
...
for (const auto& dirEntry : recursive_directory_iterator(myPath))
     std::cout << dirEntry << std::endl;

C ++ 17 के std::filesystemरूप में, मानक लाइब्रेरी का हिस्सा है और <filesystem>हेडर में पाया जा सकता है (अब "प्रयोगात्मक")।


के उपयोग से बचें using, उपयोग namespaceके बजाय।
रूई डंटन

2
और यही वजह है कि? उन चीजों को लाने से बेहतर है जो आप उपयोग नहीं करते हैं।
आदि श्वेत

कृपया मेरी संपादित करें की समीक्षा करें, मैंने भी लापता नामस्थान एसटीडी जोड़ा है।
डंटन

5
<filesystem> अब एक TS नहीं है। यह C ++ 17 का हिस्सा है। आपको शायद इस जवाब को उसी हिसाब से अपडेट करना चाहिए।
IInspectable

मैक उपयोगकर्ताओं के लिए ध्यान दें, इसके लिए OSX 10.15 (कैटालिना) की आवश्यकता होती है।
जस्टिन

45

Win32 एपीआई का उपयोग कर यदि आप उपयोग कर सकते हैं FindFirstFile और FindNextFile कार्य करता है।

http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx

निर्देशिकाओं के पुनरावर्ती ट्रावेल के लिए आपको प्रत्येक का निरीक्षण करना चाहिए ट्रावेल के लिए Win32_FIND_DATA.dwFileAttributes का कि क्या FILE_ATTRIBUTE_DIRECTORY बिट सेट है या नहीं। यदि बिट सेट है, तो आप उस निर्देशिका के साथ फ़ंक्शन को पुन: कॉल कर सकते हैं। वैकल्पिक रूप से आप एक पुनरावर्ती कॉल के समान प्रभाव प्रदान करने के लिए एक स्टैक का उपयोग कर सकते हैं लेकिन बहुत लंबे पथ के पेड़ों के लिए स्टैक ओवरफ्लो से बच सकते हैं।

#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}

int main(int argc, char* argv[])
{
    vector<wstring> files;

    if (ListFiles(L"F:\\cvsrepos", L"*", files)) {
        for (vector<wstring>::iterator it = files.begin(); 
             it != files.end(); 
             ++it) {
            wcout << it->c_str() << endl;
        }
    }
    return 0;
}

19
आपको यह लिखने में कितना समय लगा? मुझे लगता है कि अजगर को C ++ गोंद करने और इसे एक पंक्ति में करने में कम समय लगेगा।
डस्टिन गेट्ज़

2
यह एक अच्छा, गैर-पुनरावर्ती समाधान है (जो कभी-कभी काम आता है!)।
जेएम।

1
Btw, अगर कोई हार्ड-कोडेड एक ("F: \\ cvsrepos") के बजाय मार्ग के लिए कमांड-लाइन पैरामीटर argv [1] को स्वीकार करने के लिए कार्यक्रम को थोड़ा संपादित करना चाहता है, तो मुख्य (int, char) के लिए हस्ताक्षर बदल जाएगा to wmain (int, wchar_t) इस तरह: int wmain (int argc, wchar_t * argv [])
JasDev

1
धन्यवाद, लेकिन यह फ़ंक्शन सिरिलिक के साथ काम नहीं करता है। क्या इसे बनाने का कोई तरीका है जो सिरिलिक वर्णों के साथ काम करता है जैसे - बिट, रे, ऑनलाइन आदि?
unresolved_external

31

आप इसे नई C ++ 11 रेंज आधारित forऔर बूस्ट के साथ और भी सरल बना सकते हैं :

#include <boost/filesystem.hpp>

using namespace boost::filesystem;    
struct recursive_directory_range
{
    typedef recursive_directory_iterator iterator;
    recursive_directory_range(path p) : p_(p) {}

    iterator begin() { return recursive_directory_iterator(p_); }
    iterator end() { return recursive_directory_iterator(); }

    path p_;
};

for (auto it : recursive_directory_range(dir_path))
{
    std::cout << it << std::endl;
}

5
बूस्ट की जरूरत नहीं। ओपी ने विशेष रूप से मानक सी ++ के लिए कहा।
क्रेग बी

23

एक तेजी से समाधान सी के डिरेंट.एच लाइब्रेरी का उपयोग कर रहा है ।

विकिपीडिया से कार्य कोड का टुकड़ा:

#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}

5
यह दिनचर्या पुनरावर्ती नहीं है।
user501138

@ टिमकोपर, निश्चित रूप से, यह विशिष्ट विशिष्ट नहीं है।
वोरैक सिप

1
वास्तव में यह VC ++ पर काम करता है अगर आपको टोनी रोंको द्वारा विजुअल C ++ के लिए dirent.h का पोर्ट मिलता है। यह FOSS है। मैंने सिर्फ यह कोशिश की और यह काम करता है।
user1741137

10

उपर्युक्त बढ़ावा के अलावा :: फाइलसिस्टम आप wxWidgets की जांच करना चाह सकते हैं :: wxDir और Qt :: QDIR

WxWidgets और Qt दोनों ओपन सोर्स हैं, क्रॉस प्लेटफॉर्म C ++ चौखटे हैं।

wxDirपुनरावृत्ति का उपयोग करके Traverse()या एक सरल GetAllFiles()कार्य के लिए फ़ाइलों को पार करने के लिए एक लचीला तरीका प्रदान करता है । साथ ही आप ट्रैवर्सल को फ़ंक्शंस GetFirst()और GetNext()फ़ंक्शंस के साथ लागू कर सकते हैं (मेरा मानना ​​है कि ट्रैवर्स () और गेटअलीफ़ाइल्स () ऐसे रैपर हैं जो अंततः गेटफ़र्स्ट () और गेटनेक्स्ट () फ़ंक्शन का उपयोग करते हैं।

QDirनिर्देशिका संरचनाओं और उनकी सामग्री तक पहुँच प्रदान करता है। QDir के साथ निर्देशिकाओं को पार करने के कई तरीके हैं। आप QDirIterator के साथ निर्देशिका सामग्रियों (उप-निर्देशिकाओं सहित) पर पुन: प्रसारित कर सकते हैं जो QDirIterator :: Subdirectories ध्वज के साथ त्वरित किया गया था। एक और तरीका है QDir के GetEntryList () फ़ंक्शन का उपयोग करना और एक पुनरावर्ती ट्रैवर्स को लागू करना।

यहाँ नमूना कोड है ( यहाँ से लिया गया उदाहरण # 8-5) जो दिखाता है कि सभी उप निर्देशिकाओं पर पुनरावृति कैसे करें।

#include <qapplication.h>
#include <qdir.h>
#include <iostream>

int main( int argc, char **argv )
{
    QApplication a( argc, argv );
    QDir currentDir = QDir::current();

    currentDir.setFilter( QDir::Dirs );
    QStringList entries = currentDir.entryList();
    for( QStringList::ConstIterator entry=entries.begin(); entry!=entries.end(); ++entry) 
    {
         std::cout << *entry << std::endl;
    }
    return 0;
}

Doxygen अपने OS संगतता परत के रूप में qt का उपयोग करता है। मुख्य उपकरण केवल निर्देशिका सामान (और अन्य घटक) में GUI का उपयोग नहीं करते हैं।
deft_code

7

बूस्ट :: फाइलसिस्टम recursive_directory_iterator प्रदान करता है, जो इस कार्य के लिए काफी सुविधाजनक है:

#include "boost/filesystem.hpp"
#include <iostream>

using namespace boost::filesystem;

recursive_directory_iterator end;
for (recursive_directory_iterator it("./"); it != end; ++it) {
    std::cout << *it << std::endl;                                    
}

1
कृपया "यह" क्या है? क्या कोई सिंटैक्स त्रुटि नहीं है? और आप "अंत" को कैसे खिलाते हैं? (= हम कैसे जानते हैं कि हमने सभी dir को पार्स किया है?)
yO_

1
@ आप_ आप सही हैं वहाँ एक टाइपो था, recursive_directory_iterator के लिए डिफ़ॉल्ट कंस्ट्रक्टर एक "अमान्य" पुनरावृति का निर्माण करेगा, जब आपने dir पर पुनरावृति समाप्त कर दी तो यह "चालू" हो जाएगा, यह अमान्य हो जाएगा और "अंत" के बराबर होगा
DikobrAz

5

आप POSIX सिस्टम पर C या C ++ में फ़ाइल सिस्टम पदानुक्रम का उपयोग कर सकते हैं ftw(3)याnftw(3) उसका उपयोग कर सकते हैं ।


github.com/six-k/dtreetrawl/blob/… इसका एक उदाहरण है। कोड कुछ और सामान करता है, लेकिन यह nftw()उपयोग के लिए एक अच्छा ट्यूटोरियल कार्य करता है ।
छह-के

4

तुम नहीं। C ++ मानक में निर्देशिकाओं की कोई अवधारणा नहीं है। यह एक स्ट्रिंग को फ़ाइल हैंडल में बदलने के लिए लागू करना है। उस स्ट्रिंग की सामग्री और जो यह मैप करता है वह ओएस पर निर्भर है। ध्यान रखें कि C ++ का उपयोग उस OS को लिखने के लिए किया जा सकता है, इसलिए इसका उपयोग ऐसे स्तर पर किया जाता है, जहां यह पूछना कि किसी निर्देशिका के माध्यम से पुनरावृति करना अभी तक परिभाषित नहीं किया गया है (क्योंकि आप निर्देशिका प्रबंधन कोड लिख रहे हैं)।

ऐसा करने के लिए अपने ओएस एपीआई प्रलेखन को देखें। यदि आपको पोर्टेबल होने की आवश्यकता है, तो आपको विभिन्न OSes के लिए #ifdef s का एक गुच्छा रखना होगा ।


4

आप शायद बूस्ट या सी ++ 14 के प्रयोगात्मक फाइलसिस्टम सामान के साथ सबसे अच्छा होगा। यदि आप एक आंतरिक निर्देशिका को पार्स कर रहे हैं (यानी प्रोग्राम बंद होने के बाद आपके प्रोग्राम को डेटा स्टोर करने के लिए उपयोग किया जाता है), तो एक इंडेक्स फ़ाइल बनाएं जिसमें फ़ाइल सामग्री का एक इंडेक्स हो। वैसे, आपको संभवतः भविष्य में बूस्ट का उपयोग करने की आवश्यकता होगी, इसलिए यदि आपके पास यह स्थापित नहीं है, तो इसे स्थापित करें! सभी में से, आप एक सशर्त संकलन का उपयोग कर सकते हैं, जैसे:

#ifdef WINDOWS //define WINDOWS in your code to compile for windows
#endif

प्रत्येक मामले के लिए कोड https://stackoverflow.com/a/67336/7077165 से लिया गया है

#ifdef POSIX //unix, linux, etc.
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}
#endif
#ifdef WINDOWS
#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}
#endif
//so on and so forth.

2

आपको फ़ाइल-सिस्टम ट्रैवर्सल, जैसे open()और के लिए ओएस-विशिष्ट फ़ंक्शन को कॉल करने की आवश्यकता है readdir()। सी मानक किसी भी फाइलसिस्टम से संबंधित कार्यों को निर्दिष्ट नहीं करता है।


C ++ के बारे में क्या? क्या आईओस्ट्रीम में ऐसे कोई कार्य हैं?
आरोन मेंपा

2
केवल फाइलों के लिए। किसी भी तरह के "मुझे निर्देशिका में सभी फाइलें नहीं दिखाती हैं" फ़ंक्शन।
1800 सूचना

1
@ 1800: निर्देशिकाएँ फाइलें हैं।
ऑर्बिट में लाइटनेस दौड़

2

हम 2019 में हैं। हमारे पास फाइलसिस्टम मानक पुस्तकालय है C++Filesystem libraryइस तरह के रास्तों, नियमित रूप से फाइलें, और निर्देशिका के रूप में फाइल सिस्टम और उनके घटक है, पर ऑपरेशनों को करने के लिए सुविधाएं प्रदान करता है।

इस लिंक पर एक महत्वपूर्ण नोट है यदि आप पोर्टेबिलिटी के मुद्दों पर विचार कर रहे हैं। इसे कहते हैं:

यदि एक पदानुक्रमित फ़ाइल सिस्टम कार्यान्वयन के लिए सुलभ नहीं है, या यदि यह आवश्यक क्षमताओं को प्रदान नहीं करता है, तो फाइल सिस्टम लाइब्रेरी की सुविधा अनुपलब्ध हो सकती है। कुछ सुविधाएँ उपलब्ध नहीं हो सकती हैं यदि वे अंतर्निहित फ़ाइल सिस्टम द्वारा समर्थित नहीं हैं (उदाहरण के लिए FAT फाइल सिस्टम में प्रतीकात्मक लिंक का अभाव है और कई हार्डलिंक को मना करता है)। उन मामलों में, त्रुटियों की सूचना दी जानी चाहिए।

फाइलसिस्टम लाइब्रेरी को मूल रूप से विकसित किया boost.filesystemगया था, तकनीकी विनिर्देश आईएसओ / आईईसी टीएस 18822: 2015 के रूप में प्रकाशित किया गया था, और अंत में सी ++ 17 के रूप में आईएसओ सी ++ में विलय कर दिया गया था। बूस्ट कार्यान्वयन वर्तमान में C ++ 17 पुस्तकालय की तुलना में अधिक संकलक और प्लेटफार्मों पर उपलब्ध है।

@ adi-shavit ने इस सवाल का जवाब दिया है जब यह std :: प्रयोगात्मक का हिस्सा था और उन्होंने 2017 में इस उत्तर को अपडेट किया है। मैं पुस्तकालय के बारे में अधिक विवरण देना चाहता हूं और अधिक विस्तृत उदाहरण दिखाना चाहता हूं।

std :: फाइल सिस्टम :: recursive_directory_iterator है एक LegacyInputIteratorहै कि एक निर्देशिका के directory_entry तत्वों, और, रिकर्सिवली, सभी सबडायरेक्टरियों की प्रविष्टियों से अधिक से अधिक दोहराता। पुनरावृति क्रम अनिर्दिष्ट है, सिवाय इसके कि प्रत्येक निर्देशिका प्रविष्टि केवल एक बार देखी जाती है।

यदि आप उपनिर्देशिकाओं की प्रविष्टियों पर पुनरावृत्ति नहीं करना चाहते हैं, तो directory_iterator का उपयोग किया जाना चाहिए।

दोनों iterators की एक वस्तु देता है directory_entrydirectory_entryजैसे विभिन्न उपयोगी सदस्य कार्य करता है is_regular_file, is_directory, is_socket, is_symlinkआदि path()सदस्य समारोह रिटर्न की एक वस्तु std :: फाइल सिस्टम :: पथ और इसे पाने के लिए इस्तेमाल किया जा सकता file extension, filename, root name

नीचे दिए गए उदाहरण पर विचार करें। मैं उपयोग कर रहा हूं Ubuntuऔर टर्मिनल का उपयोग करके इसे संकलित कर रहा हूं

g ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall

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

void listFiles(std::string path)
{
    for (auto& dirEntry: std::filesystem::recursive_directory_iterator(path)) {
        if (!dirEntry.is_regular_file()) {
            std::cout << "Directory: " << dirEntry.path() << std::endl;
            continue;
        }
        std::filesystem::path file = dirEntry.path();
        std::cout << "Filename: " << file.filename() << " extension: " << file.extension() << std::endl;

    }
}

int main()
{
    listFiles("./");
    return 0;
}

1

तुम नहीं। मानक सी ++ एक निर्देशिका की अवधारणा को उजागर नहीं करता है। विशेष रूप से यह किसी निर्देशिका में सभी फ़ाइलों को सूचीबद्ध करने का कोई तरीका नहीं देता है।

एक भयानक हैक प्रणाली () कॉल का उपयोग करने और परिणामों को पार्स करने के लिए होगा। सबसे उचित समाधान कुछ प्रकार के क्रॉस-प्लेटफॉर्म लाइब्रेरी जैसे कि क्यूटी या यहां तक ​​कि पॉसिक्स का उपयोग करना होगा


1

आप उपयोग कर सकते हैं std::filesystem::recursive_directory_iterator। लेकिन सावधान रहें इसमें प्रतीकात्मक (नरम) लिंक शामिल हैं। यदि आप उनसे बचना चाहते हैं तो आप उपयोग कर सकते हैं is_symlink। उदाहरण उपयोग:

size_t directorySize(const std::filesystem::path& directory)
{
    size_t size{ 0 };
    for (const auto& entry : std::filesystem::recursive_directory_iterator(directory))
    {
        if (entry.is_regular_file() && !entry.is_symlink())
        {
            size += entry.file_size();
        }
    }
    return size;
}

1
पिछले नहीं बल्कि कम से कम, वास्तव में पिछले उत्तरों से बेहतर है।
सैयद मेहरान सियादती

0

यदि आप विंडोज पर हैं, तो आप फाइंडनस्टाइल एपीआई के साथ फाइंडफ्रस्टाइल का उपयोग कर सकते हैं। आप दिए गए पथ फ़ाइल या निर्देशिका है या नहीं यह जानने के लिए FindFileData.dwFileAttributes का उपयोग कर सकते हैं। यदि यह एक निर्देशिका है, तो आप एल्गोरिथम को पुन: दोहरा सकते हैं।

यहां, मैंने कुछ कोड को एक साथ रखा है जो सभी फाइलों को विंडोज मशीन पर सूचीबद्ध करता है।

http://dreams-soft.com/projects/traverse-directory


0

फ़ाइल ट्री वॉक ftwपथ में पूरी निर्देशिका ट्री की दीवार को पुनरावर्ती करने के लिए एक पुनरावर्ती तरीका है। अधिक जानकारी यहाँ हैं

नोट: आप भी उपयोग कर सकते हैं ftsउस तरह छिपा फ़ाइलों को छोड़ सकते हैं .या ..या.bashrc

#include <ftw.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>

 
int list(const char *name, const struct stat *status, int type)
{
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         printf("0%3o\t%s\n", status->st_mode&0777, name);
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
}

int main(int argc, char *argv[])
{
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
}

आउटपुट निम्न जैसा दिखता है:

0755    ./Shivaji/
0644    ./Shivaji/20200516_204454.png
0644    ./Shivaji/20200527_160408.png
0644    ./Shivaji/20200527_160352.png
0644    ./Shivaji/20200520_174754.png
0644    ./Shivaji/20200520_180103.png
0755    ./Saif/
0644    ./Saif/Snapchat-1751229005.jpg
0644    ./Saif/Snapchat-1356123194.jpg
0644    ./Saif/Snapchat-613911286.jpg
0644    ./Saif/Snapchat-107742096.jpg
0755    ./Milind/
0644    ./Milind/IMG_1828.JPG
0644    ./Milind/IMG_1839.JPG
0644    ./Milind/IMG_1825.JPG
0644    ./Milind/IMG_1831.JPG
0644    ./Milind/IMG_1840.JPG

यदि आप *.jpg, *.jpeg, *.pngकिसी विशिष्ट आवश्यकताओं के लिए फ़ाइल नाम (उदाहरण: सभी फ़ाइलों की खोज करना ) का उपयोग करना चाहते हैं, तो हमें बताएं fnmatch

 #include <ftw.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <iostream>
 #include <fnmatch.h>

 static const char *filters[] = {
     "*.jpg", "*.jpeg", "*.png"
 };

 int list(const char *name, const struct stat *status, int type)
 {
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         int i;
         for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
             /* if the filename matches the filter, */
             if (fnmatch(filters[i], name, FNM_CASEFOLD) == 0) {
                 printf("0%3o\t%s\n", status->st_mode&0777, name);
                 break;
             }
         }
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         //printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
 }

 int main(int argc, char *argv[])
 {
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.