لغة C++ ليست فقط للألعاب وبرامج التشغيل
\n\nعندما تسمع "C++"، غالبًا ما تتخيل الأسلحة الثقيلة: محركات Unreal، أنظمة التشغيل، الخوادم عالية الأداء. ولكن هناك جانب آخر لا يقل فائدة — أتمتة المهام بلغة C++. بينما يكتب زملاؤك سكريبتات Bash المؤقتة أو يعانون من تبعيات Python، يمكنك بناء أداة مدمجة وسريعة تعمل لسنوات دون الحاجة لتحديث المفسر.
\n\nفي هذه المقالة، سأوضح لك كيفية تحويل C++ إلى سكين سويسري للأتمتة. سنستعرض أمثلة واقعية: من إعادة تسمية الملفات دفعة واحدة إلى تحليل السجلات وإنشاء التقارير. ستكتشف أن أتمتة الروتين بلغة C++ ليست صعبة، بل هي مربحة جدًا من حيث السرعة والموثوقية.
\n\nلماذا C++ بدلاً من Python أو Bash؟
\n\nلكل لغة مكانها. لكن هناك سيناريوهات تتفوق فيها C++:
\n\n- \n
- سرعة التنفيذ. إذا كنت تعالج تيرابايت من السجلات — فكل ملي ثانية لها أهميتها. \n
- عدم وجود تبعيات. ملف ثنائي واحد مُجمّع بشكل ثابت يعمل على أي نظام Linux/Windows دون الحاجة لتثبيت مفسر. \n
- أمان الأنواع. مفاجآت أقل في وقت التشغيل — أمر حاسم للأتمتة التي تعمل وفق جدول زمني. \n
- الوصول المباشر للنظام. العمل المباشر مع WinAPI وPOSIX والسجل والعمليات — بدون طبقات وسيطة. \n
بالطبع، للنمذجة السريعة، Python أكثر ملاءمة. لكن عندما يصبح السكريبت جزءًا من CI/CD أو البنية التحتية للإنتاج، فإن الأتمتة بلغة C++ تؤتي ثمارها بشكل كبير.
\n\nالأدوات: ما تحتاج معرفته
\n\nلمهامنا، لسنا بحاجة إلى C++20 بأكمله. يكفي مجموعة أساسية:
\n\n- \n
std::filesystem(C++17) — التعامل مع الملفات والمجلدات \nstd::regex— تحليل النصوص \nstd::fstream/std::stringstream— القراءة والكتابة \nstd::chrono— قياس الوقت وتسجيله \n
قم بالتجميع باستخدام العلم -std=c++17 (أو /std:c++17 لـ MSVC).
مثال 1: إعادة تسمية الملفات دفعة واحدة
\n\nتخيل: لديك مجلد به صور IMG_001.jpg، IMG_002.jpg … تحتاج إلى تحويلها إلى تنسيق 2025_01_15_001.jpg. يدويًا — 10 دقائق من العمل الممل. باستخدام سكريبت — 0.2 ثانية.
الكود
\n#include <iostream>\n#include <filesystem>\n#include <regex>\n#include <string>\n\nnamespace fs = std::filesystem;\n\nint main() {\n std::string dir_path = "./photos";\n std::regex pattern(R"(IMG_(\\d+)\\.jpg)");\n std::string prefix = "2025_01_15_";\n\n for (auto &entry : fs::directory_iterator(dir_path)) {\n std::string filename = entry.path().filename().string();\n std::smatch match;\n\n if (std::regex_match(filename, match, pattern)) {\n std::string new_name = prefix + match[1].str() + ".jpg";\n fs::rename(entry.path(), entry.path().parent_path() / new_name);\n std::cout << "تمت إعادة التسمية: " << filename << " -> " << new_name << "\\n";\n }\n }\n return 0;\n}\n\nيوضح هذا المثال كيف أن أتمتة المهام بلغة C++ باستخدام std::filesystem والتعبيرات المنتظمة تحل مشكلة يومية ببضعة أسطر. يمكنك تكييفه بسهولة مع أنماطك الخاصة.
مثال 2: تحليل السجلات وحساب الأخطاء
\n\nلنفترض أن الخادم يكتب سجلات بالتنسيق التالي:
\n2025-01-15 10:23:45 [ERROR] فشل الاتصال بقاعدة البيانات\n2025-01-15 10:23:46 [INFO] المحاولة رقم 1\n2025-01-15 10:23:47 [ERROR] تجاوز المهلة\n\nنحتاج إلى جمع إحصائيات: كم عدد الأخطاء من كل نوع، وعرض أكثر 5 رسائل تكرارًا. سكريبت Bash ذو السطر الواحد قد يفي بالغرض، لكن إذا كانت السجلات بحجم جيجابايت — ستكون C++ أسرع بكثير.
\n\nالكود
\n#inc