هل هناك طريقة لاستخدام fopen_s () مع دول مجلس التعاون الخليجي أو على الأقل إنشاء #Define حول هذا الموضوع؟
-
19-09-2019 - |
سؤال
يقول مترجم MSVC ذلك fopen()
تم إهمالها، وتوصي باستخدام fopen_s()
.
هل هناك أي طريقة للاستخدام fopen_s()
وما زلت محمولة؟
أي أفكار ل #define
?
المحلول
مايكروسوفت *_s
وظائف غير قابلة للذين، وأي عادة استخدام وظائف C89 / C99 المكافئة وتعطيل تحذيرات الإهمال (#define _CRT_SECURE_NO_DEPRECATE
).
إذا كنت تصر، فيمكنك استخدام وظيفة محول (وليس بالضرورة ماكرو!) التي المندوبين fopen()
على المنصات التي لا تملك fopen_s()
, ، ولكن يجب أن تكون حريصا على خريطة قيم errno_t
إرجاع رمز من errno
.
errno_t fopen_s(FILE **f, const char *name, const char *mode) {
errno_t ret = 0;
assert(f);
*f = fopen(name, mode);
/* Can't be sure about 1-to-1 mapping of errno and MS' errno_t */
if (!*f)
ret = errno;
return ret;
}
ومع ذلك، أفشل في معرفة كيف fopen_s()
هو أكثر أمانا من fopen()
, ، لذلك عادة ما أذهب لتقليل القدرة.
نصائح أخرى
إذا كنت تستخدم C11، fopen_s
هي مكتبة قياسية:
http://en.cppreference.com/w/c/io/fopen.
في gcc
تحتاج إلى استخدام --std=C11
معامل.
في رمز C / C ++،
#ifdef __unix
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL
#endif
في makefile.
CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL'
الانتباه إلى أنه على النجاح FOPEN_S العودة 0 بينما FOPEN إرجاع مؤشر ملف غير صفري. لذلك من الضروري إضافة "== NULL" إلى نهاية الماكرو، على سبيل المثال:
if (fopen_s(&pFile,filename,"r")) perror("cannot open file");
يتم تضمين العديد من وظائف Microsoft الآمنة في الملحق K من معيار C11، لكنه غير مدعوم على نطاق واسع، لذلك لا تزال قابلية النقل مشكلة. هناك حاجة إلى تحسين الأمن في بعض التطبيقات؛ ربما سوف يتحسن الدعم في المستقبل.
أنا الماضي، لقد فعلت ذلك مثل هذا:
#define fopen_s(fp, fmt, mode) *(fp)=fopen( (fmt), (mode))
ماكرو بسيط ومباشر إلى الأمام، جيد بما يكفي لشيء سريع وقذرة، لكنه لا يوفر سلوك الاستثناء من FOPEN_S، ولن يوفر أمان وظيفة FOPEN_S الحقيقية.
يتسبب نهج دالة EXEX B أعلاه جزئيا في استنساخ السلوك المناسب على الفشل؛ يعيد errno (= einval). يمكن تمديد نهجه أكثر من خلال توليد استثناء المعلمة غير صالح إلى إعادة إنتاج سلوك FOPEN_S بالكامل.
#define fopen_s(fp, fmt, mode) ({\
*(fp)=fopen( (fmt), (mode));\
(*(fp) ) ? 0:errno;\
})
accroding إلى https://en.cppreference.com/w/c/io/fopen. من الممكن تمكين * _s وظائف على المكتبة القياسية:
كما هو الحال مع جميع الوظائف التي تم فحصها،
fopen_s
مضمونة فقط لتكون متاحة إذا__STDC_LIB_EXT1__
يتم تعريفه من خلال التنفيذ وإذا كان المستخدم يحدد__STDC_WANT_LIB_EXT1__
إلى عدد صحيح1
قبل بما في ذلك<stdio.h>
.