Thread: strcpy vs sprintf

  1. #1
    Registered User Tiago's Avatar
    Join Date
    Oct 2009
    Location
    Lisbon, Portugal
    Posts
    28

    strcpy vs sprintf

    Hi guys... and girls, if any... xD

    Can someone tell me the main difference between strcpy and sprintf?

    They are going to be used here:

    Code:
    typedef struct type_node{
        char string[1024];
        char character;
        int integer;
        type_vector * vector;
        struct type_node * next;
    }type_node;
    
    type_node * new_node(char file_name[1024], int file_index, type_vector * file_data){
        type_node * new_node;
        new_node = (type_node *) malloc(sizeof(type_node));
        if (new_node == NULL){
            exit(-1);
        }
    
    
        /* strcpy vs sprintf */
    
        strcpy(new_node->string, file_name);
    
        /* OR */
    
        sprintf(new_node->string, "%s", file_name);
    
        /* EO(strcpy vs sprintf) */
    
    
        new_node->integer = file_index;
        new_node->vector = file_data;
        new_node->seg = NULL;
        return new_node;
    }

    regards
    Last edited by Tiago; 12-07-2009 at 05:17 PM. Reason: missed a ";"

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Don't use strcpy, but strncpy (it is more safe)

    Code:
    strncpy(char *dest, const char *src, int n);
    sprintf(char *dest, const char *fmt, ...);
    strncpy copies n bytes from src to dest, where sprintf copies data to a string based upon the fmt string.

    strncpy takes 3 variables, sprintf takes at least 2.

    The list goes on. . .

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Your usage of sprintf() is incorrect. The correct equivalent of strcpy() would be:
    Code:
    sprintf(new_node->string, "%s", file_name);
    sprintf() builds a new string based upon a format string. It is similar to printf(), but instead of printing the resulting string, it copies it into the passed buffer.
    bit∙hub [bit-huhb] n. A source and destination for information.

  4. #4
    Registered User Tiago's Avatar
    Join Date
    Oct 2009
    Location
    Lisbon, Portugal
    Posts
    28
    thanks for the replies...

    Quote Originally Posted by bithub View Post
    Your usage of sprintf() is incorrect. The correct equivalent of strcpy() would be:
    Code:
    sprintf(new_node->string, "%s", file_name);
    sprintf() builds a new string based upon a format string. It is similar to printf(), but instead of printing the resulting string, it copies it into the passed buffer.
    Yes, you were right...

    ... afterall they all do the same... i'm going to use sprintf... seems fancier xD
    I was wondering if there was a very good reason to use one and not the other... at least in this particular case...

  5. #5
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    In this case, sprintf() needs to scan the format string before doing the copy. In other words, strcpy() gives you much better performance (I'm willing to bet it's over twice as fast).
    bit∙hub [bit-huhb] n. A source and destination for information.

  6. #6
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by Kennedy View Post
    Don't use strcpy, but strncpy (it is more safe)
    Would like to comment on that, since I have seen it a lot.
    Reading about strncpy I see that it also pads the destination string with zeros. Meaning that you might get a worse performance.
    Consider somebody might use:
    Code:
    char str[1024];
    cp = "hey";
    strncpy(str, cp, sizeof(str));
    You would be copying unecessary data everytime. You can think that you then can use sizeof(cp) instead. Yeah, but then why use it when strcpy() would do the same thing?

    I believe this function was meant to be used to copy a substring as given the example here rather than being used for safety.

    Somebody will argue and say that the first example offers a safe way to copy every possilbe string to "str" w/o worrying of causing a segmentation fault by copying more elements than the size of "str". But what is worst? Causing a segmentation fault of copying a substring of a string when you wanted the whole string? Most of the times I would prefer the segmentation fault. It tells you "there is something wrong!". Logical errors are more difficult to spot. Imagine copying somewhere "Stat" instead of "State" because you used strncpy thinking only about safety. Of course strcpy() can do worse things than seg fault and create problems even less likely to be spotted, like changing a value of another variable.

    So, the morale is that if you misuse them you can cause problems. The only way to make sure is to check what you are copying to what. But if strncpy() was only for safety reasons, why pad with zeros? It would just work as strcpy() but stop copying if more characters than the "num" parameter were inserted. For example, fgets() will stop reading input if newline is found or a number of characters are read. It won't pad the buffer with zeros. So you would say fgets() was created for safety reasons exclusively.

    In any case, if you want a safe strcpy() you should make your own function. Something like
    Code:
    int sstrcpy(char* des, const char* src)
    {
         if (sizeof(src) > sizeof(des)) return -1;
         strcpy(des, src); 
         return 0;
    }
    Personally, this is what I would expect from a safe copy string.

    My advise is to read exactly what a function does. And never be bored to make your own functions in C if they are simple. It makes sense for the standard functions to offer high performance sacrifising safety. Why? Because if strcpy() did what I posted, you wouldn't be able to have a faster non-safe strcpy(). In most cases going from non-safe to safe is easier rather than going from safe to non-safe but faster.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    strncpy isn't better anyway, because it doesn't guarantee that the string is null terminated.

    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by C_ntua
    You would be copying unecessary data everytime. You can think that you then can use sizeof(cp) instead. Yeah, but then why use it when strcpy() would do the same thing?
    You should actually use the minimum of the sizes of the source and destination arrays, and that also answers the question of why one should use strncpy() instead of strcpy() in a context where the sizes are not known beforehand. In this case, I would actually prefer to use strcpy() since the source string is hardcoded and its size appears to be guaranteed.

    Quote Originally Posted by C_ntua
    In any case, if you want a safe strcpy() you should make your own function. Something like
    Like, yes, but what your example has a serious flaw
    It uses sizeof to try and determine the size of an array given only a pointer to an element within the array, but of course one would only get the size of the pointer.

    However, I agree that it would be better to define another function instead of using strncpy(), because as what quzah pointed out, one can forget to add the null terminator to account for edge cases when using strncpy().
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Which is better: to read over an unterminated string -- thus reading into memory that may or may not belong to the user OR WRITE over the end of a buffer?

    I tend to think it is the former rather than the latter.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Kennedy
    Which is better: to read over an unterminated string -- thus reading into memory that may or may not belong to the user OR WRITE over the end of a buffer?
    Why choose between the lesser of two evils when you can choose the good?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Using strncpy can result in truncation, which in itself can be disastrous. A better way is to use strcpy like this:

    Code:
    if (input_len > buffer_len)
        /* handle the error /*
    else
        strcpy(buffer, input);

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Memloop
    Using strncpy can result in truncation, which in itself can be disastrous. A better way is to use strcpy like this:
    Refer to C_ntua's example in post #6. It has the same idea once you fix the flawed use of sizeof. However, if the input itself is not guaranteed to contain a null terminator, then the use of strcpy() in implementing that function is still flawed.
    Last edited by laserlight; 12-08-2009 at 10:10 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

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. Sprintf overflows my buffer -- why?
    By Lasston in forum C Programming
    Replies: 26
    Last Post: 06-20-2008, 04:33 PM
  3. Strcpy
    By Godders_2k in forum C Programming
    Replies: 17
    Last Post: 12-12-2007, 12:34 PM
  4. sprintf and sscanf
    By tommy69 in forum C Programming
    Replies: 10
    Last Post: 04-22-2004, 08:00 PM
  5. Sprintf
    By Trauts in forum C++ Programming
    Replies: 10
    Last Post: 01-15-2003, 01:35 PM