Difference between strncpy and memcpy?
Asked Answered
I

6

25

How can I access s[7] in s?

I didn't observe any difference between strncpy and memcpy. If I want to print the output s, along with s[7] (like qwertyA), what are the changes I have to made in the following code:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char s[10] = "qwerty", str[10], str1[10];
    s[7] = 'A';
    printf("%s\n", s);
    strncpy(str, s, 8);
    printf("%s\n", str);
    memcpy(str1, s, 8);
    printf("%s\n", str1);
    return 0;
}

Output:

qwerty
qwerty
qwerty
Ibert answered 4/1, 2011 at 13:6 Comment(2)
Try swapping memcpy and strncpy in your above code. Then experience the difference.Queensland
Another difference is type checking and the type returned. Important in other cases, not here.Bakker
E
51

Others have pointed out your null-termination problems. You need to understand null-termination before you understand the difference between memcpy and strncpy.

The main difference is that memcpy will copy all N characters you ask for, while strncpy will copy up to the first null terminator inclusive, or N characters, whichever is fewer.

In the event that it copies less than N characters, it will pad the rest out with null characters.

Edi answered 4/1, 2011 at 13:16 Comment(3)
There's another difference as well, strncpy will fill the rest of the space with 0. e.g. if you do strncpy(a,b,255); and a is 10 long, strncpy will copy those 10 characters and fill the remaining 240 characters with 0.Erikerika
@nos: I realized that before you did, and edited it in. But thanks anyway :)Edi
Also consider: "No null-character is implicitly appended at the end of destination if source is longer than num. Thus, in this case, destination shall not be considered a null terminated C string (reading it as such would overflow)."Micrococcus
K
8

You are getting the output querty because the index 7 is incorrect (arrays are indexed from 0, not 1). There is a null-terminator at index 6 to signal the end of the string, and whatever comes after it will have no effect.

Two things you need to fix:

  1. Change the 7 in s[7] to 6
  2. Add a null-terminator at s[7]

The result will be:

char s[10] = "qwerty";
s[6] = 'A';
s[7] = 0;

Original not working and fixed working.

As for the question of strncpy versus memcpy, the difference is that strncpy adds a null-terminator for you. BUT, only if the source string has one before n. So strncpy is what you want to use here, but be very careful of the big BUT.

Kizzie answered 4/1, 2011 at 13:10 Comment(0)
T
4

Strncpy will copy up to NULL even you specified the number of bytes to copy , but memcpy will copy up to specified number of bytes .

printf statement will print up to NULL , so you will try to print a single charater , it will show ,

printf("\t%c %c %c\t",s[7],str[7],str1[7]);

OUTPUT

  7              7
Typhoeus answered 12/10, 2012 at 11:37 Comment(0)
M
2

To make "qwertyA" you need to set s[6] = 'A' and s[7]='\0'

Strings are indexed from 0, so s[0] == 'q', and they need to be null terminated.

Mylonite answered 4/1, 2011 at 13:10 Comment(5)
I should not change s[7] to s[6]. If we set s[6] as 'A' then we will get the desired output..Ibert
@user so you're saying you don't want the desired output? O_oEdi
@user559208: when marcog wrote "change s[6] to s[7]" I think he actually meant instead of writing s[7], write s[6]. Also, don't forget the null termination of the string (setting s[7] to 0 or '\0') because that will help prevent overrun bugs from creeping in.Mylonite
You might be right about the confusion there. I've attempted to make the wording clearer.Kizzie
@marcog: That's clearer now. Also, sorry for the minor misquote!Mylonite
E
2

When you have:

char s[10] = "qwerty";

this is what that array contains:

s[0]  'q'
s[1]  'w'
s[2]  'e'
s[3]  'r'
s[4]  't'
s[5]  'y'
s[6]   0
s[7]   0
s[8]   0
s[9]   0

If you want to add an 'A' to the end of your string, that's at index 6, since array indexes start at 0

 s[6] = 'A';

Note that when you initialize an array this way, the remaining space is set to 0 (a nul terminator), While not needed in this case, generally be aware that you need to make your strings nul terminated. e.g.

char s[10];
strcpy(s,"qwerty");
s[6] = 'A';
s[7] = 0;

In the above example "qwerty" , including its nul terminator is copied to s. s[6] overwrites that nul terminator. Since the rest of s is not initialized we need to add a nul terminator ourselves with s[7] = 0;

Erikerika answered 4/1, 2011 at 13:53 Comment(0)
M
1

As explained by Philip Potter, the main difference is that memcpy will copy all n characters you ask for, while strncpy will copy up to the first null terminator inclusive, or n characters, whichever is less. In the event that strncpy copies less than N characters, it will pad the rest out with null characters. The below program will answer your question:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char s[10] = "qwerty",str1[10];
    int i;
    s[7] = 'A';
    memcpy(str1, s, 8);
    for(i=0;i<8;i++)
    {
        if(str1[i]!='\0')
            printf("%c",str1[i]);
    }
    return 0;
}

o/p:

qwertyA

Execute the below code and check the difference, you might find it useful.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char s[10] = "qwer\0ty", str[10], str1[10];
    s[7] = 'A';
    printf("%s\n",s);
    strncpy(str,s,8);
    printf("%s\n",str);
    memcpy(str1,s,8);
    printf("%s\n",str1);
    for(int i = 0; i<8; i++)
    {
        printf("%d=%c,",i,str[i]);
    }
    printf("\n");
    for(int i = 0; i<8; i++)
    {
        printf("%d=%c,",i,str1[i]);
    }
    return 0;
}

Output:

qwer
qwer
qwer
0=q,1=w,2=e,3=r,4=,5=,6=,7=,
0=q,1=w,2=e,3=r,4=,5=t,6=y,7=A,
Mooned answered 10/12, 2021 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.