هل هناك طريقة لاستخدام fopen_s () مع دول مجلس التعاون الخليجي أو على الأقل إنشاء #Define حول هذا الموضوع؟

StackOverflow https://stackoverflow.com/questions/1513209

  •  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>.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top