Thread: strcpy prototype

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    11

    strcpy prototype

    As i wrestle my way to the book"teach yourself C in 21 days", more and more questions turn up in my head ...

    Ok here is the question:
    this is the prototype of strcpy():

    Code:
    char *strcpy(char *destination, const char *source);
    the source string must be a "const char *" If i got this correct that means a pointer to a char. this pointer value cannot change, because it is const (am i right ?? ).
    That would mean you only can copy an array as "source".

    I wrote a small programm to test this, and the first time i use a "const char *" (array) as "source", the next strcpy i use a pointer to an array (thus not "const char *").

    The output is the same both times.... Can someone explain, i'm confused.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
          /* fill the arrays with sample data, leaving room for the 0 */
          char string1[10] = "abcdefghi";
          char string2[10];
          char string3[10] = "jklmnopqr";
    
          /* pointer to an char */
          char *arrayptr;
    
          /* this is how its suppose to be i think ... */
          strcpy(string2, string1);
          printf("string 1 is: %s\n", string1);
          printf("string 2 is: %s\n", string2);
    
    
          /* arrayptr is not const char * */
          arrayptr = string3;
    
          /*here the source is not const char * */
          strcpy(string2, arrayptr);
          printf("string 1 is: %s\n", string1);
          printf("string 2 is: %s\n", string2);
    
          system("PAUSE");
          return 0;
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually,
    Code:
    const char *
    means that the content that it points to can't change. If you want a pointer that can't in itself be changed, then it is
    Code:
    char * const
    As far as strcpy is concerned, it would be quite stupid to have a strcpy() that modifies the original - if your photocopier or fax-machine where changing/destroying your original when you copy, you would ask for it to be repaired/replaced, right? So for strcpy() to have the second argument (the original) to be const is perfectly valid and correct. The destination is intendend to be modified, so it should not be a const.

    Edit: Also, you can always "add" const to something, but you should never remove const from a type. So a non-const input to the source of strcpy() is fine - but you can't pass a const char * type to the destination (and it would probably be silly to do so, since whoever constructed the string didn't expect it to change, so you shouldn't be changing it).
    --
    Mats
    Last edited by matsp; 08-29-2008 at 05:46 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jul 2008
    Posts
    11
    Ok clear, thank you for the fast reply!.

  4. #4
    Registered User
    Join Date
    Jan 2008
    Posts
    66
    An array is not a "const char *" pointer to it's first element, only it's address is const, but the data that resides in that location is not const.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by ThLstN View Post
    An array is not a "const char *" pointer to it's first element, only it's address is const, but the data that resides in that location is not const.
    The address of an array is technically "char * const", but it's traditionally not done that way, because lots of old code would break if you enforce that [and of course, since the pointer is a local variable argument to a function (and thus a copy of the value of the pointer), making the pointer itself const simply means that you can't "walk" the input variable, but have to make a copy [and remove the constness], which just makes stuff messy.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    On a side note, you shouldn't use strcpy in your programs. It's vulnerable to buffer overflow attacks. Not necessarily something you need to be concerned with now, but if you ever write programs for an unknown user base, it becomes very important. There are variations out there that will take an extra parameter of the maximum number of characters to copy. Look for strlcpy or strncpy.

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Would it not be better to say "You should never copy user-provided data" with strcpy - I expect it is perfectly safe to do something like this:
    Code:
    char filename[MAX_PATH];
    ... 
    strcpy(filename, "noname.cpp");
    ... 
    // but this is bad:
    strcpy(filename, requestNameFromUser());
    because the user could potentially provide a name that doesn't fit in our filename.

    Edit: And of course, if you need to remember one rule for everything, strncpy() is the one to use.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    But strncpy has its own quirks, so it's best to research it properly before expanded use. For simply beginner programs, strcpy and no error checking is usually fine.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >The output is the same both times.... Can someone explain, i'm confused.
    It's a safe conversion from char* to const char*. Think of it like this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
      /* fill the arrays with sample data, leaving room for the 0 */
      char string1[10] = "abcdefghi";
      char string2[10];
      char string3[10] = "jklmnopqr";
    
      /* pointer to an char */
      char *arrayptr;
    
      /* char *strcpy ( char *s1, const char *s2 ) */
      {
        char *__s1 = string2;
        const char *__s2 = string1;
    
        while ( ( *__s1++ = *__s2++ ) != '\0' )
          ;
      }
    
      /*strcpy(string2, string1);*/
      printf("string 1 is: %s\n", string1);
      printf("string 2 is: %s\n", string2);
    
    
      /* arrayptr is not const char * */
      arrayptr = string3;
    
      /* char *strcpy ( char *s1, const char *s2 ) */
      {
        char *__s1 = string2;
        const char *__s2 = arrayptr;
    
        while ( ( *__s1++ = *__s2++ ) != '\0' )
          ;
      }
    
      /*strcpy(string2, arrayptr);*/
      printf("string 1 is: %s\n", string1);
      printf("string 2 is: %s\n", string2);
    
      return 0;
    }
    In a way you're adding the const qualifier to arrayptr for the duration of the strcpy call by assigning it to another pointer with the const qualifier. This is safe (though the reverse is not) because you're assigning to a more restrictive type.

    >On a side note, you shouldn't use strcpy in your programs.
    >It's vulnerable to buffer overflow attacks.
    If you fail to validate your data and program defensively, sure. In other words, strcpy is only vulnerable to buffer overflow attacks if your code was inherently unsafe to begin with. If you don't know how to write safe code using strcpy, then by all means use something that protects you from your ignorance, but a blanket ban on a function is silly unless it can't be made safe through good programming practices (like gets).
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A Full Program to analyze.
    By sergioms in forum C Programming
    Replies: 2
    Last Post: 12-30-2008, 09:42 AM
  2. Strcpy
    By Godders_2k in forum C Programming
    Replies: 17
    Last Post: 12-12-2007, 12:34 PM
  3. Replies: 13
    Last Post: 08-24-2006, 12:22 AM
  4. Function prototype questions
    By Kayoss in forum C++ Programming
    Replies: 6
    Last Post: 11-30-2005, 05:27 PM
  5. Prototype syntax for sub-class constructor
    By starkhorn in forum C++ Programming
    Replies: 1
    Last Post: 10-08-2004, 07:33 AM