0

I am using the function strcpy() a lot for an assignment. Looking at the function prototype for strcpy():

char *strcpy(char *dest, const char *src)

It can be seen that strcpy() takes in two pointers.

However, I have seen in a lot of examples online as well as in my own code that a string can be copied in the following manner and it will work:

char array[30];
strcpy(array, "mystring");
printf("%s\n", array);

My question is, why does strcpy() work if the second parameter that you're passing is a string? Wouldn't the second parameter need be a pointer to a string? E.g. wouldn't you have to do the following:

const char *str = "mystring";
char array[30];
strcpy(array, str);
printf("%s\n", array);

I'm confused about why you can directly pass a string as the second parameter to strcpy() and not a pointer to the string. Any insights would be really appreciated.

Priya
  • 334
  • 3
  • 8
ceno980
  • 2,003
  • 1
  • 19
  • 37

3 Answers3

3

Because in C the type of a string literal is char[] : http://c0x.coding-guidelines.com/6.4.5.html

[...For character string literals, the array elements have type char...]

Jose
  • 3,306
  • 1
  • 17
  • 22
  • Wouldn't you have to assign the string literal to a variable prior to using it in strcpy (e.g. char *x = "string")? Or is it just fine to pass the string directly, since it'll be reduced to a pointer? – ceno980 Jul 19 '18 at 09:53
  • 1
    @ceno980 It doesn't matter when the array decays to a pointer. – Deduplicator Jul 19 '18 at 10:06
  • @ceno980 If a literal already has a machting type as you need, copying to a variable doesn't gain anything. – Gerhardh Jul 19 '18 at 10:26
1

This is due to the special relationship between arrays and pointers in C.

Formally, a string in C is an array of char. But pointers in C can very easily be used to access arrays, such that 'pointer to char' is often as useful a type for manipulating strings as 'array of char' is. Furthermore, any time you use an array (including a string constant) in an expression where its value is needed, what you get (automatically) is a pointer to the array's first element.

That is, if you say

char array[10];
char *p = array;

it is precisely as if you had said

char *p = &array[0];

And since a string constant (formally, a string literal) is an array of char, if you say

p = "mystring";

or

strcpy(array, "mystring");

it is exactly as if you had said

p = &"mystring"[0];

or

strcpy(array, &"mystring"[0]);

So you don't need to add your own & in these cases, and if you do, it's not quite right, because what you end up with is 'pointer to array' rather than 'pointer to char' which is what you want.

The syntax &"mystring"[0] is very strange, and no one would ever use it, and it probably makes this explanation pretty confusing. Let's do it a slightly different way. If you say

char mystring[] = "mystring";
p = mystring;

or

strcpy(array, mystring);

it is exactly as if you had said

p = &mystring[0];

or

strcpy(array, &mystring[0]);

When you call strcpy(array, &mystring[0]) you are passing a char * to strcpy, as required. If you were to call

strcpy(array, &mystring);   /* WRONG */

you would be passing a 'pointer to array of char' (or char *[]) instead, which would be wrong. (It might even end up seeming to work, which might confuse you into thinking it was proper, but it's not.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
0

I'm confused about why you can directly pass a string as the second parameter to strcpy() and not a pointer to the string. Any insights would be really appreciated.

You do have to pass a pointer to a c-string for both arguments, or at least something that can decay to such a pointer. The type char array char[] (which is the type of string literals) can do that.

Remember though that a c-string is not a type. It is a continuous sequence of bytes terminated by the first \0.

Here is an enlightening example:

char c[30] = "Hello\0 \0World!\n";
printf("%s%s%s\n", &c[0],&c[6],&c[8] );

The char array c has size 30. It contains three c-strings: "Hello", " ", and "World!\n". Their lengths are 5, 1, and 7 and the amount of space they occupy in the array is 6, 2, and 8 respectively.

klutt
  • 30,332
  • 17
  • 55
  • 95