strcpy ... تريد استبدالها ب strcpy_mine والتي سوف تنهي strncpy و null

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

  •  11-09-2019
  •  | 
  •  

سؤال

الدليل موجود في العنوان ولكن أساسا لقد ورثت بعض الكود التي لديها 800+ مثيلات من strcpy. أريد أن أكتب وظيفة جديدة ثم استبدال strcpy مع strcpy_mine.

لذلك أنا أحاول العمل من قائمة المعلمات strcpy_mine سيكون لها.

حاولت:

void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
  const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
  strncpy( pTarget, pCopyMe, lenAlwaysFour );

  //add extra terminator in case of overrun
  pTarget[lenAlwaysFour] = 0;
}

لكن المقرض هو دائما 4 pcopyme هو مؤشر

ما لا أريد القيام به هو استبدال

strcpy (buf, pCopyMe);

مع

strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;

أيه أفكار؟ (strcpy_l غير متوفر)

في صحتك

هل كانت مفيدة؟

المحلول

اعتمادا على كيفية تشبيه مواقع المكالمات، غالبا غالبية الحالات يمكن التعامل معها بواسطة قالب بسيط:

#include <string.h>

template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
  strncpy( pTarget, pCopyMe, bufferSize-1 );

  //add extra terminator in case of overrun
  pTarget[bufferSize-1] = 0;
}

int main()
{
  char buf[128];
  strcpy_mine(buf,"Testing");
  return 0;
}

إذا كنت تستخدم Microsoft Visual Studio 2005 أو أحدث، انظر قالب آمن الزائد لتنفيذ مايكروسوفت.

نصائح أخرى

Sizeof () إرجاع حجم النوع - في هذه الحالة const char* const والتي ستكون 4 على 32 بت الآلات.

أعتقد أنك تعتقد أنك تريد strlen(). وبعد ولكن هذه ليست هي الطريقة الصحيحة لاستخدام وظائف strncpy. تحتاج إلى حجم انتاج العازلة ل strncpy.

لإصلاح ذلك، تحتاج إلى فحص التعليمات البرمجية في كل موقع استدعاء، وتستخدم حجم المخزن المؤقت الإخراج، وتمرير ذلك كوسيطة ل strcpy_mine. وبعد إذا كان موقع المكالمات ل STRCPY (أو strcpy_mine) لا يعرف حجم المخزن المؤقت الإخراج، فأنت بحاجة إلى البحث إلى الوراء في التعليمات البرمجية للموقع الذي يخصص المخزن المؤقت، وتمرير الحجم إلى موقع Strcpy وبعد

في الأساس لا يمكنك كتابة انخفاض في استبدال STRCPY الذي يأخذ نفس الحجج والأمل في تجنب المشاكل التي أنتجت strncpy في المقام الأول (واستبدال أفضل وراء ذلك). يمكنك إنشاء وظيفة تأخذ نفس الحجج مثل strncpy، ولكنها تضمن أن النتيجة هي التي تم إنهاءها - انظر إلى تنفيذ openbsd's strlcpy () وظيفة. ولكن الخطوة الأولى يجب أن تكون لتغيير مواقع الدعوة لتمرير معرفة حجم المخزن المؤقت الإخراج.

محيطي قليلا ربما، ولكن منذ أن ذكره لا أحد، يتم التباهي في العنوان: لا يمكنك (قانونيا) كتابة وظيفة عالمية تسمى strcpy_mine().

"مساحة الاسم" للوظائف التي تبدأ أسماءها str محجوز للمكتبة القياسية. انظر، على سبيل المثال، الإجابة المقبولة على هذا السؤال.

يمكنك استخدام نفس قائمة المعلمات باعتبارها strncpy ل strcpy_mine الخاص بك، ولكن اكتبها بحيث تنتهي النتيجة دائما. لا ينبغي أن يكون من الصعب جدا القيام به.

بعض التحدي، ومع ذلك، هو أن بعض الكود الحالي الخاص بك الذي يستدعي strcpy () قد لا يعرف حجم المخزن المؤقت، إما.

يمكنك أيضا استخدام وحدات ما صغيرة لتجنب تحرير متعددة. أو أتمتة التحرير عبر بعض النصي.

تحتاج بالتأكيد إلى تمرير حجم المخزن المؤقت الوجهة كمعلمة، كما قال أشخاص آخرون أعلاه.

هذا هو نوع من الموضوع خارج الموضوع، ولكن أريد فقط أن أشير إلى ذلك، بعد استخدام strncpy(), ، تحتاج إلى ضبط على الحرف الأخير من المخزن المؤقت، الذي لديه فهرس 1 أقل من الطول (وليس طول المخزن المؤقت):

strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';

أو بدلا من ذلك، يمكنك استخدام strncat() على سلسلة فارغة، تمريرها بطول 1 أقل، وسوف يضمن لإنهاء سلسلة الخاص بك:

buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);

Douglas Leeder لديه صحيح. هناك حد لفائدة استبدال STRCPY إلا إذا كنت على استعداد للقيام بعمل نخر من المرور في طول المخزن المؤقت الصالح والعكس في كل حالة. هذا كثير من العمل!

الأخبار الجيدة هي أنه يستحق كل هذا العناء! مرة أخرى منذ بضع سنوات، جئت في العديد من مشاريع C ++ التي كانت متأخرة وعربات التي تجرها الدواب وغير موثوق بها. بإعلان STRCPY و Strlen ممنوع، وأخذ 2-3 أيام من المشروع لتحل محلها مع مخصص STRNCPY / Strnlen، في كل هذه المشاريع التي يمكن أن نهرب فجأة لعدة أيام بدلا من ساعات. شاهدنا أيضا الكثير من السلاسل المقطوعة التي تظهر على شاشات العرض وملفات السجل. قدم لنا القرائن اللازمة لتعقب قضايا اقتطاع القضايا التي تحطمها سابقا.

إذا كنت لا ترغب في القيام بذلك، فيمكنك الحصول على فائدة أصغر بكثير من خلال التحقق من كلا من معلمات المؤشرات ل Null، والحد من الحد الأقصى لحجم نسخة واحدة و تسجيل جميع الأوقات التي يتم بها الوصول إلى الحدود. لا تقم بإجراء strlen من أي معلمة، حيث أن Strlen سوف تعطل لحسن الحظ عليك إذا كانت السلسلة ليست فارغة بشكل صحيح.

في الوقت الحاضر، تستخدم مشاريع جديدة كائنات سلسلة جيدة، ولكن هناك الكثير من الشفرة القديمة هناك لا.

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