sprintf / snprintf
تحويل عدد إلى نص بأمان sprintf / snprintf
sprintf تكتب نصًا منسّقًا لمصفوفة بدون أي حد لحجمها، بينما snprintf تأخذ حجم المخزن كمعامل فتمنع تجاوز الحدود.
sprintf تعمل مثل printf لكنها تكتب النتيجة لمصفوفة char بدل الشاشة، دون أي فحص لحجم تلك المصفوفة — لو كان النص الناتج أطول من المخزن يحدث تجاوز حدود (buffer overflow)، وهذا أحد أشهر أسباب الثغرات الأمنية في برامج C القديمة.
snprintf تحل هذه المشكلة بإضافة معامل الحجم: تكتب حتى size-1 حرفًا وتضيف \0 دائمًا ضمن الحدود المتاحة. القيمة التي تُرجعها هي عدد الأحرف التي كانت ستُكتب لو كان المخزن كافيًا — لو كانت هذه القيمة أكبر من أو تساوي size فهذا يعني حدوث اقتطاع.
الصياغة
int sprintf(char *buf, const char *format, ...); int snprintf(char *buf, size_t size, const char *format, ...);
📄 مثال
char safe[10];
int needed = snprintf(safe, sizeof(safe), "%d-%d", 12345, 6789);
if (needed >= (int)sizeof(safe)) {
// النتيجة اقتُطعت — احتجنا مخزنًا أكبر
}أهم النقاط
| العنصر | الوظيفة |
|---|---|
| buf | المصفوفة الوجهة التي يُكتب فيها النص |
| size (في snprintf فقط) | الحد الأقصى للبايتات المكتوبة بما فيها \0 |
| القيمة المُرجَعة | عدد الأحرف الذي كان سيُكتب لو كان المخزن كافيًا، بدون احتساب \0 |
💡 نصائح عملية
- استخدم snprintf بدل sprintf دائمًا، تمامًا متل تفضيل fgets على gets
- مرّر sizeof(buf) كمعامل الحجم مباشرة بدل رقم ثابت لتفادي عدم التطابق لو تغيّر حجم المصفوفة
⚠️ أخطاء شائعة
- استخدام sprintf بمخزن حجمه غير مضمون كفايته لمدخلات متغيّرة الطول
- تجاهل القيمة المُرجَعة من snprintf وعدم التحقق من حدوث اقتطاع
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار C الكامل بالعربي.