How to copy a string into a char array in C++ without going over the buffer

前端 未结 11 937
Happy的楠姐
Happy的楠姐 2020-12-08 03:13

I want to copy a string into a char array, and not overrun the buffer.

So if I have a char array of size 5, then I want to copy a maximum of 5 bytes from a string in

相关标签:
11条回答
  • 2020-12-08 03:41
    void stringChange(string var){
    
        char strArray[100];
        strcpy(strArray, var.c_str()); 
    
    }
    

    I guess this should work. it'll copy form string to an char array.

    0 讨论(0)
  • 2020-12-08 03:43

    Some nice libc versions provide non-standard but great replacement for strcpy(3)/strncpy(3) - strlcpy(3).

    If yours doesn't, the source code is freely available here from the OpenBSD repository.

    0 讨论(0)
  • 2020-12-08 03:43

    Update: Thought I would try to tie together some of the answers, answers which have convinced me that my own original knee-jerk strncpy response was poor.

    First, as AndreyT noted in the comments to this question, truncation methods (snprintf, strlcpy, and strncpy) are often not a good solution. Its often better to check the size of the string string.size() against the buffer length and return/throw an error or resize the buffer.

    If truncation is OK in your situation, IMHO, strlcpy is the best solution, being the fastest/least overhead method that ensures null termination. Unfortunately, its not in many/all standard distributions and so is not portable. If you are doing a lot of these, it maybe worth providing your own implementation, AndreyT gave an example. It runs in O(result length). Also the reference specification returns the number of bytes copied, which can assist in detecting if the source was truncated.

    Other good solutions are sprintf and snprintf. They are standard, and so are portable and provide a safe null terminated result. They have more overhead than strlcpy (parsing the format string specifier and variable argument list), but unless you are doing a lot of these you probably won't notice the difference. It also runs in O(result length). snprintf is always safe and that sprintf may overflow if you get the format specifier wrong (as other have noted, format string should be "%.<N>s" not "%<N>s"). These methods also return the number of bytes copied.

    A special case solution is strncpy. It runs in O(buffer length), because if it reaches the end of the src it zeros out the remainder of the buffer. Only useful if you need to zero the tail of the buffer or are confident that destination and source string lengths are the same. Also note that it is not safe in that it doesn't necessarily null terminate the string. If the source is truncated, then null will not be appended, so call in sequence with a null assignment to ensure null termination: strncpy(buffer, str.c_str(), BUFFER_LAST); buffer[BUFFER_LAST] = '\0';

    0 讨论(0)
  • 2020-12-08 03:47
    std::string str = "Your string";
    char buffer[5];
    strncpy(buffer, str.c_str(), sizeof(buffer)); 
    buffer[sizeof(buffer)-1] = '\0';
    

    The last line is required because strncpy isn't guaranteed to NUL terminate the string (there has been a discussion about the motivation yesterday).

    If you used wide strings, instead of sizeof(buffer) you'd use sizeof(buffer)/sizeof(*buffer), or, even better, a macro like

    #define ARRSIZE(arr)    (sizeof(arr)/sizeof(*(arr)))
    /* ... */
    buffer[ARRSIZE(buffer)-1]='\0';
    
    0 讨论(0)
  • 2020-12-08 03:48

    First of all, strncpy is almost certainly not what you want. strncpy was designed for a fairly specific purpose. It's in the standard library almost exclusively because it already exists, not because it's generally useful.

    Probably the simplest way to do what you want is with something like:

    sprintf(buffer, "%.4s", your_string.c_str());
    

    Unlike strncpy, this guarantees that the result will be NUL terminated, but does not fill in extra data in the target if the source is shorter than specified (though the latter isn't a major issue when the target length is 5).

    0 讨论(0)
提交回复
热议问题