मैं एक सी ++ कंसोल एप्लिकेशन विकसित कर रहा हूं जिसे विंडोज ओएस पर फाइलों का प्रबंधन करना है। मुझे फ़ाइल नामों की एक 'सूची' प्राप्त करने की आवश्यकता है जिसमें एक विशिष्ट एक्सटेंशन है। मुझे बहुत सारे समाधान मिल गए हैं, सबसे अधिक सुझाया गया समाधान निम्नलिखित है:
HANDLE hFind;
WIN32_FIND_DATA data;
hFind = FindFirstFile("C:\\PWS\\*.sda", &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
cout << data.cFileName << endl;
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
मान लीजिए मेरे पास ये फ़ाइलें C:\\PWS
फ़ोल्डर के अंदर हैं:
- f001.sdac
- f002.sda
- f003.sdab
- f004.sda
उपरोक्त कोड उन सभी को प्रिंट करता है, जबकि मुझे केवल f002.sda
और f004.sda
की आवश्यकता है।
कोई संकेत?
NB
: मैं बूस्ट लाइब्रेरी का उपयोग नहीं करना चाहता।
3 जवाब
मैंने जो समाधान अपनाया वह निम्नलिखित है:
void GetFilesByNameRootAndExtension(const string& dirPath, const string& nameRoot, string& ext, vector<string>& files)
{
files.clear();
stringstream ss;
ss << dirPath << "\\" << nameRoot << "*" << ext;
string searchKeyS = ss.str();
const char* searchKey = searchKeyS.c_str();
WIN32_FIND_DATA data;
HANDLE hFind = FindFirstFile(searchKey, &data);
ext = ext.erase(0, 1);
if (hFind != INVALID_HANDLE_VALUE) {
do {
string fN = data.cFileName;
if (fN.substr(fN.find_last_of(".") + 1) == ext) // filtering by extension
files.push_back(fN);
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
आपके संकेतों के लिए सभी को धन्यवाद!
कोड "f001.sdac"
और "f003.sdab"
भी ढूंढता है क्योंकि FindFirstFile()
और FindFirstFileEx()
छोटे (8.3) और लंबे फ़ाइल नामों से मेल खाते हैं। उदाहरण के लिए, "f001.sdac"
के लिए संक्षिप्त फ़ाइल नाम "f~1.sda"
जैसा कुछ हो सकता है।
इसका कारण है 16-बिट के साथ पश्चगामी संगतता (आहें!) कार्यक्रम.
इस समस्या को हल करने के लिए, सभी फाइलों से मेल खाने के लिए *
वाइल्डकार्ड के साथ FindFirstFile()
को कॉल करें और फिर अपनी खुद की फ़िल्टरिंग करें, उदाहरण के लिए PathMatchSpec()
फ़ंक्शन। PathMatchSpec()
केवल स्ट्रिंग मिलान करता है इसलिए इसमें FindFirstFile()
का अजीब व्यवहार नहीं है।
WIN32_FIND_DATAW data;
HANDLE hFind = FindFirstFileW( L"C:\\PWS\\*", &data );
if( hFind != INVALID_HANDLE_VALUE )
{
do
{
if( ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 &&
PathMatchSpecW( data.cFileName, L"*.sda" ) )
{
std::wcout << data.cFileName << std::endl;
}
}
while( FindNextFileW( hFind, &data ) );
FindClose( hFind );
}
साइड नोट: fInfoLevelId
पैरामीटर के लिए FindExInfoBasic
के मान के साथ FindFirstFileEx()
को कॉल करना, जो माना जाता है कि "संक्षिप्त फ़ाइल नाम को क्वेरी नहीं करता", इस समस्या के लिए मान्य समाधान नहीं है क्योंकि यह अभी भी छोटे (8.3) फ़ाइल नामों से मेल खाएगा।
ऐसा कुछ आपके लिए परिणामों को फ़िल्टर करना चाहिए:
bool hasFileExtension(TCHAR cFileName[], TCHAR* ptcExtension)
{
bool result = true;
int iFileNameLength = _tcslen(cFileName);
int iExtensionLength = _tcslen(ptcExtension);
if (iFileNameLength >= iExtensionLength)
{
for (int i = 1; i < iExtensionLength + 1 && result; i++)
{
if (cFileName[iFileNameLength - i] != ptcExtension[iExtensionLength - i])
{
result = false;
}
}
}
else
{
result = false;
}
return result;
}
void listFilesWithExtension(LPCTSTR lpFileName, TCHAR* ptcExtension)
{
HANDLE hFind;
WIN32_FIND_DATA data;
hFind = FindFirstFile(lpFileName, &data);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (hasFileExtension(data.cFileName, ptcExtension))
{
wcout << data.cFileName << endl;
}
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
int main()
{
LPCTSTR lpFileName = L"C:\\PWS\\*.sda";
TCHAR* ptcExtension = _T(".sda");
listFilesWithExtension(lpFileName, ptcExtension);
Sleep(5000);
return 0;
}
संबंधित सवाल
जुड़े हुए प्रश्न
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।