snprintf和strcpy和strncpy的区别

snprintfstrcpystrncpy这几个函数的功能都是将原字符串拷贝到目的字符串中。但是在细节部分还是存在着一些细微的差别。主要参考man说明。

snprintf

格式

int snprintf(char *str, size_t size, const char *format, ...);

说明

The functions snprintf() and vsnprintf() write at most size bytes (including the terminating null byte (‘\0’)) to str.

即,snprintf会把源字符串拷贝到目的地址。如果源字符串的长度大于约束条件size,那么会拷贝size - 1个字符到目的地址,并将最后一个字符赋值为'\0'

例子

#include <iostream>
#include <string.h>
using namespace std;
int main() {
    char buf[10] = {0};
    snprintf(buf, 10, "hello word");
    cout << buf << ", " << strlen(buf) << ", " << sizeof(buf) <<  endl;
    return 0;
}

输出结果如下:

可以看出,目的内存buf只能存放10个字符,而"hello word"加上最后的'\0',总共有11个字符,因此snprintf最多拷贝9个字符到buf中,并将最后一个字符设置为'\0'

strcpy

格式

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

说明

The strcpy() function copies the string pointed to by src, including the terminating null byte (‘\0’), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.

strcpysrc整个字符串(包括“\0”)拷贝到dest中。如果src字符串(包括“\0”)的长度大于dest的空间大小,会导致数组越界的bug

例子

#include <iostream>
#include <string.h>
using namespace std;
int main() {
    char buf[8] = {0};
    char buf1[8] = {0};
    char buf2[8] = {0};
    //snprintf(buf, 10, "hello word");
    //strncpy(buf1,  "hello wrod_nice", 10);
    strcpy(buf1,  "hello word");
    //cout << buf << ", " << strlen(buf) << ", " << sizeof(buf) <<  endl;
    cout << buf1 << ", " << strlen(buf1) << ", " << sizeof(buf1) <<  endl;
    cout << buf2 << ", " << strlen(buf2) << ", " << sizeof(buf2) <<  endl;
    return 0;
}

输出结果如下:

可以看出,原本拷贝到buf1中的数据,覆盖了buf2中的数据。

strncpy

格式

char *strncpy(char *dest, const char *src, size_t n);

说明

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated. If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written.

strncpysnprintf的区别在于,如果srcn个字符没有包含"\0",那么strncpy不会将"\0"拷贝到dst中。

例子

int main() {
    char buf[8] = {0};
    char buf1[8] = {0};
    char buf2[8] = {0};
    //snprintf(buf, 10, "hello word");
    strncpy(buf1,  "hello word", 8);
    //strcpy(buf1,  "hello word");
    //cout << buf << ", " << strlen(buf) << ", " << sizeof(buf) <<  endl;
    cout << buf1 << ", " << strlen(buf1) << ", " << sizeof(buf1) <<  endl;
    cout << buf2 << ", " << strlen(buf2) << ", " << sizeof(buf2) <<  endl;
    return 0;
}

输出如下图所示

同样的,我们看一下bufbuf1buf2的内容。buf2的内容并未被覆盖,但是buf1的最后一个字符是o而不是"\0"

Tags: c++语法
Share: X (Twitter) Facebook LinkedIn