سؤال

ماهو الفرق بين memcpy() و strcpy()؟ حاولت العثور عليه بمساعدة البرنامج ولكن كلاهما يعطي نفس الإخراج.

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    strcpy(p,s);
    memcpy(t,s,5);
    printf("sachin p is [%s], t is [%s]",p,t);
    return 0;
}

انتاج |

sachin p is [sa], t is [sa]
هل كانت مفيدة؟

المحلول

ما يمكن فعله لرؤية هذا التأثير

تجميع وتشغيل هذا الرمز:

void dump5(char *str);

int main()
{
    char s[5]={'s','a','\0','c','h'};

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;
}

void dump5(char *str)
{
    char *p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%2.2x ", *p);
        ++p;
    }

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%c", *p ? *p : ' ');
        ++p;
    }

    printf("\n", str);
}

سوف ينتج هذا المخرج:

73 61 00 63 68  sa ch
73 61 00 00 00  sa

يمكنك أن ترى أنه تم نسخ "CH" memcpy(), ، لكن لا strcpy().

نصائح أخرى

strcpy يتوقف عندما يواجه نول ('\0') حرف، memcpy لا. أنت لا ترى التأثير هنا ، %s في printf يتوقف أيضا في نول.

strcpy ينتهي عندما يتم العثور على Terminator الفارغ من السلسلة المصدر. memcpy يتطلب تمرير معلمة الحجم. في الحالة التي قدمتها printf يتوقف البيان بعد العثور على Terminator NULL لكلا صفيفات الأحرف ، ومع ذلك ستجد t[3] و t[4] لقد نسخت البيانات فيها أيضًا.

strcpy نسخ الحرف من مصدر إلى الوجهة واحدة تلو الأخرى حتى تجد شخصية فارغة أو ' 0' في المصدر.

while((*dst++) = (*src++));

بينما memcpy نسخ البيانات (وليس الحرف) من مصدر إلى الوجهة من حجم معين ، بغض النظر عن البيانات في المصدر.

memcpy يجب استخدامه إذا كنت تعرف جيدًا أن هذا المصدر يحتوي على غير الشخصية. بالنسبة للبيانات المشفرة أو البيانات الثنائية ، تعد Memcpy طريقة مثالية للذهاب.

strcpy تم إهماله ، لذا استخدم strncpy.

بسبب الشخصية الفارغة في الخاص بك s سلسلة ، printf لن تظهر أي شيء يتجاوز ذلك. الفرق بين p و t سيكون في الشخصيات 4 و 5. p لن يكون لها أي (سيكونون القمامة) و t سوف يكون 'c' و 'h'.

  • اختلاف السلوك: strcpy يتوقف عندما يواجه أ NULL أو '\0'
  • فرق الأداء: memcpy عادة ما يكون أكثر كفاءة من strcpy, ، التي تقوم دائمًا بمسح البيانات التي تقوم بنسخها

الفرق الرئيسي هو ذلك memcpy() يقوم دائمًا بنسخ العدد الدقيق للبايتات التي تحددها ؛ strcpy(), ، من ناحية أخرى ، سوف نسخ حتى يقرأ بايت (ويعرف أيضًا باسم 0) ، ثم توقف بعد ذلك.

المشكلة في برنامج الاختبار الخاص بك هي أن printf() يتوقف عن إدخال الحجة في %s, ، عندما تواجه نهاية فارغة \0. لذلك في إخراجك ربما لم تلاحظ ذلك ، ذلك memcpy() نسخ الشخصيات c و h كذلك.

لقد رأيت في GNU glibc-2.24, ، هذا (ل x86) strcpy() فقط مكالمات memcpy(dest, src, strlen(src) + 1).

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