sprintf 功能的强大不会让你失望,接下来我们先入门sprintf函数
int sprintf(char *str, const char *format, ...)
如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数
#define _USE_MATH_DEFINES 1 //如果要使用里面的宏,需要定义_USE_MATH_DEFINES
#include
#include
int main()
{
char str[80];
sprintf(str, "Pi 的值 = %f", M_PI);
puts(str);
return(0);
}
#include
int main()
{
char dest[20];
sprintf(dest, "Hello World!");
puts(dest);
}
#include
int main()
{
int num = 886;
char str[] = "goodby";
char dest[20];
sprintf(dest, "%s is %d", str, num);
puts(dest);
}
sprintf函数的返回值不包含目标字符串末尾自动添加的'\0'
#include
int main()
{
int num = 886;
char str[] = "goodby";
char dest[20];
int len = sprintf(dest, "%s is %d", str, num);
puts(dest);
printf("len = %d\n", len);
}
产生10个[0, 100)之间的随机数,并将他们打印到一个字符数组s中,以逗号分隔开,最后一个数字后面是换行。
#include
#include
#include
int main()
{
char dest[40];
srand(time(NULL)); //置随机数种子
int offset = 0;
for (int i = 0; i < 9; i++)
{
offset +=sprintf(dest+ offset, "%d,", rand() % 100);
}
//最后一个数后面添加一个换行
offset += sprintf(dest + offset, "%d\n", rand() % 100);
int len = strlen(dest);
for (int i = 0; i < len; i++)
{
printf("%c", dest[i]);
}
}
spirntf第一个参数注意
注意当你想要在一个字符数组的某个位置开始时,那么第一个参数就要传对应位置的地址。
int main()
{
char dest[40] = "I love ";
char str[] = "this world!";
//sprintf(dest + 7, "%s", str);
sprintf(dest + 7, str);
puts(dest);
return 0;
}
1、格式化字符数组
int main()
{
char a[100] = { 0 };
sprintf(a, "你好,我是%s博主", "PiDan");
printf("%s\n", a);
return 0;
}
2. 字符串的拼接
int main()
{
char dest[100];
char str1[] = "Hello";
char str2[] = "Word!";
int len1 = sprintf(dest, "%s, % s", str1, str2);
printf("%s\n%d", dest, len1);
return 0;
}
3. 数字转换成字符串 -> sprintf
#include
void IntToString(int num, char* str)
{
sprintf(str, "%d", num);
return str;
}
int main()
{
int number1 = 123456;
int number2 = -123456;
char string[16] = { 0 };
IntToString(number1, string);
printf("数字:%d 转换后的字符串为:%s\n", number1, string);
IntToString(number2, string);
printf("数字:%d 转换后的字符串为:%s\n", number2, string);
return 0;
}
3. 字符串转整数-> atoi
函数原型:int atoi(const char *nptr);//字符串转整数函数,nptr: 要转换的字符串
#include
#include
int main()
{
printf("字符串\"123456\"转换为数字:%d\n", atoi("123456"));
printf("字符串\"-123456\"转换为数字:%d\n", atoi("-123456"));
return 0;
}
1、sprintf函数引起的缓冲区溢出
int main()
{
char src[50] = "abcdefghijklmnopqrstuvwxyz";
char buf[10] = "";
int len = sprintf(buf, "%s", src);
printf("src=%s\n", src);
printf("len=%d\n", len);
printf("buf=%s\n", buf);
return 0;
}
现象&后果
程序运行时,用sprintf函数把字符数组src的内容往字符数组buf复制时会溢出,可能出现段错误(Segmentation fault)。
Bug分析
上述代码从一个字符数组src复制字符串到另外一个字符数组buf中,src的字符串长度为26,但buf的长度只有10,用sprintf函数进行复制的时候会把src的所有字符往buf里写,从而引起buf溢出。
正确的做法是在复制之前检查buf的长度是否足够,或者直接用更安全的snprintf函数代替sprintf。
正确代码
int main()
{
char src[50] = "abcdefghijklmnopqrstuvwxyz";
char buf[10] = "";
int len = snprintf(buf, sizeof(buf), "%s", src);
if (len > sizeof(buf) - 1)
{
printf("[Error] Source string length is %d. The buf size %d is not enough. Copy incomplete!\n", len, sizeof(buf));
}
else
{
printf("src=%s\n", src);
printf("len=%d\n", len);
printf("buf=%s\n", buf);
}
return 0;
}