sprintf和snprintf所需头文件: #include <stdio.h>
1. sprintf
int sprintf(char *string, char *format [,argument,...]);
参数: string: 要写入的缓冲区
format: 要写入string中数据的格式,例如%s、%d、%x等
argument: 等待写入的内容
返回值: 写入str的字节数,结束字符‘\0’不计入内。
举例一:
int main(){
char str[20];
sprintf(str, "this is: %s", "hello");
cout << str << endl;
}
输出如下:
this is: hello
考虑一个问题,如果拷贝的字符串长度大于分配的内存大小会怎样?
举例二:
int main(){
char str[20];
sprintf(str, "this is: %s", "hello, I'm alsa.");
cout << str << endl;
}
上面的代码编译不会出错,运行到函数退出时程序就会直接crash,因为sprintf时用到了没分配的内存,退出时内存无法释放掉就会crash。
sprintf的另外一个用法就是把不同类型的数据转化为char*格式连接起来。
举例三:
int main()
{
char str[20];
sprintf(str, "%s + %d", "hello", 100);
cout << str << endl;
}
上面的代码输出结果:
hello + 100(100的存储为‘1’ ‘0’ ‘0’占三个字符)
此处需要特别注意各种类型数据占用的字符长度。
2. snprintf
int snprintf(char *str, size_t size, const char *format, ...);
参数: string: 要写入的缓冲区
size: 设置写入str的大小
format: 要写入str中数据的格式,例如%s、%d、%x等
argument: 等待写入的内容
返回值: 若成功则返回预写入的字符串长度,若出错则返回负值。(注意!此处是预写入!!!)
注意: snprintf在写入的时候会有判断,如果写入的大小超过了str的内存大小就会终止写入。
举例一:
int main()
{
char str1[20];
char* buffer = "hello.";
int len = snprintf(str1, 20, "this is: %s", buffer);
cout << str1 << endl;
cout << "len is: " << len << endl;
}
输出如下:
this is: hello.
len is: 15(此处是预写入的长度)
举例二:
int main()
{
char str1[20];
char* buffer = "hello, I'm alsa.";
int len = snprintf(str1, 20, "this is: %s", buffer);
cout << str1 << endl;
cout << "len is: " << len << endl;
}
输出:
this is: hello, I'm(此处包含'/0'一共20个字符)
len is: 25(此处是预写入的长度,不是实际写入长度)
举例三:
int main()
{
char str1[20];
char* buffer = "hello, I'm alsa.";
int len = snprintf(str1, 30, "this is: %s", buffer);
cout << str1 << endl;
cout << "len is: " << len << endl;
}
输出:
this is: hello, I'm alsa.
len is: 25
然后在程序退出时crash。
综上,sprintf和snprintf的重要区别就是snprintf有size参数,可以控制写入的字符长度,避免内存越界的问题。但是此处也要注意设置的size大小要小于等于str内存的大小。
ps: 本人写代码的教训,下不为例!