لماذا قد تحتاج إلى قائمة الملفات في C++؟
تخيل: أنت تكتب برنامجًا يجب أن يعالج مئات ملفات السجلات، أو يتحقق من وجود ملفات التكوين، أو ببساطة يعرض للمستخدم ما يوجد في المجلد. بدون القدرة على "النظر" داخل الدليل، ستواجه حائطًا مسدودًا. لهذا السبب يعتبر سؤال «How can I get the list of files in a directory using C or C++?» من أكثر الأسئلة شيوعًا على Stack Overflow. واليوم سنقوم بتحليله بالكامل.
في المقال، سأعرض ثلاث طرق رئيسية: من الطريقة الكلاسيكية بأسلوب C (تعمل في كل مكان ولكنها تتطلب الدقة) إلى الطريقة الحديثة C++17 std::filesystem (موجزة وآمنة وجميلة). ستتعلم كيفية اختيار الأداة المناسبة لمهمتك، وستحصل على أمثلة جاهزة للكود يمكنك إدراجها فورًا في مشروعك.
الطريقة 1: الكلاسيكية — dirent.h (POSIX / Linux / macOS)
هذه الطريقة هي "الجد" لجميع الحلول. تُستخدم في C و C++ على الأنظمة الشبيهة بـ Unix. الفكرة بسيطة: تفتح الدليل، تقرأ الإدخالات واحدًا تلو الآخر، ثم تغلقه. لا تعقيدات، ولكن تحكم كامل.
التضمين والهياكل
ستحتاج إلى:
#include <dirent.h>— للعمل مع الدلائلDIR *dir— مؤشر لتيار الدليلstruct dirent *entry— هيكل يحتوي على اسم الملف
مثال كود: عرض بسيط لجميع الأسماء
#include <iostream>#include <dirent.h>
int main() { const char* path = "."; // المجلد الحالي DIR* dir = opendir(path); if (dir == nullptr) { std::cerr << "فشل فتح الدليل: " << path << std::endl; return 1; }
struct dirent* entry; while ((entry = readdir(dir)) != nullptr) { std::cout << entry->d_name << std::endl; }
closedir(dir); return 0;}ملاحظات مهمة
- الدالة
readdir()ترجع الأسماء.(الدليل الحالي) و..(الدليل الأصلي). عادةً يجب تخطيهما:
if (entry->d_name[0] == '.') continue;- هذا الكود **لا يعمل على Windows** بشكل افتراضي. بالنسبة لـ Windows، يوجد
windows.hوFindFirstFile/FindNextFile(سنتحدث عنه لاحقًا). - الإيجابيات: بساطة، يعمل بدون C++17. السلبيات: غير متعدد المنصات، لا يوجد تصفية حسب نوع الملف.
الطريقة 2: Windows API — FindFirstFile و FindNextFile
إذا كان هدفك هو Windows، انسَ dirent.h. بدلاً من ذلك، استخدم WinAPI الأصلي. إنه قوي، لكن الكود يصبح مطولاً.
كيف يعمل
- استدعاء
FindFirstFileمع نمط (مثل"C:\\\\*"). - الحصول على مؤشر (handle) وأول إدخال.
- في حلقة، استدعاء
FindNextFileحتى يعيد 0. - إغلاق المؤشر عبر
FindClose.
مثال: قائمة الملفات في جذر القرص C:
#include <iostream>#include <windows.h>
int main() { WIN32_FIND_DATA findFileData; HANDLE hFind = FindFirstFile("C:\\\\*", &findFileData);
if (hFind == INVALID_HANDLE_VALUE) { std::cerr << "فشل العثور على الملفات (رمز الخطأ: " << GetLastError() << ")" << std::endl; return 1; }
do { // تخطي "." و ".." if (strcmp(findFileData.cFileName, ".") != 0 && strcmp(findFileData.cFileName, "..") != 0) { std::cout << findFileData.cFileName << std::endl; } } while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind); return 0;}ما هو مهم معرفته
- في
WIN32_FIND_DATAيوجد حقلdwFileAttributesالمدونات
توصيات الكتب
اقرأ أيضًا