Memcpy,字符串和终结符

Dan*_*ilo 6 c c++ string terminator

我必须编写一个函数,用一个字符串的内容填充指定长度的char*缓冲区.如果字符串太长,我只需要剪掉它.缓冲区不是由我分配的,而是由我的函数用户分配的.我试过这样的事情:

int writebuff(char* buffer, int length){
    string text="123456789012345";
    memcpy(buffer, text.c_str(),length);
    //buffer[length]='\0';
    return 1;
}


int main(){
    char* buffer = new char[10];
    writebuff(buffer,10);
    cout << "After: "<<buffer<<endl;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是关于终结者:它应该存在与否?这个函数用在更广泛的代码中,有时候当我需要剪切字符串时,我会遇到奇怪字符的问题.

有关正确程序的任何提示吗?

Mar*_*som 7

C样式字符串必须以零字符终止'\0'.

此外,您的代码还有另一个问题 - 它可能会尝试从源字符串的末尾复制.这是经典的未定义行为.看起来它可能看起来有效,直到有一次在堆内存块的末尾分配字符串并且副本进入受保护的内存区域并且失败了.您应该只复制到缓冲区长度的最小值或字符串的长度.

PS为了完整性,这是一个很好的功能版本.感谢Naveen指出终止null中的off-by-one错误.我冒昧地使用你的返回值来表示返回字符串的长度,或者传入的长度<= 0时所需的字符数.

int writebuff(char* buffer, int length)
{
    string text="123456789012345";
    if (length <= 0)
        return text.size();
    if (text.size() < length)
    {
        memcpy(buffer, text.c_str(), text.size()+1);
        return text.size();
    }
    memcpy(buffer, text.c_str(), length-1);
    buffer[length-1]='\0';
    return length-1;
}
Run Code Online (Sandbox Code Playgroud)


Nav*_*een 7

如果要将缓冲区视为字符串,则应将NULL终止.为此,您需要使用复制length-1字符并将字符memcpy设置length-1\0.