c字符串函数sprintf()和snprintf()详解

sprintf()是个变参函数,定义格式如下:

int sprintf( char *buffer, const char *format [, argument] … );

精华显然在于第二个字符串:格式化字符串
1.格式化数字字符串
sprintf最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代itoa(把一个整数转换为字符串)。
//把整数打印成一个字符串并保存在字符串中

sprintf(str,"%d",890);

//可以指定宽度,不足的左边补空格

sprintf(str,"%6d%6d",123,456);

//左对齐,右边补空格

sprintf(str,"%-6d%6d",123,456);

2.连接字符串
在很多长河中可以替代strcat,中间可以插入很多内容,非常灵活

char *op = who;
char *ret = you;
sprintf(str,"%s are %s",op,ret);

strcat 只能连接字符串(一段以 ‘\0’ 结尾的字符数组或叫做字符缓冲,null-terminated-string),但有时我们有两段字符缓冲区,他们并不是以 ‘\0’ 结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的 ‘\0’ 来结尾。如果直接连接,不管是 sprintf 还是 strcat 肯定会导致非法内存操作,而 strncat 也至少要求第一个参数是个 null-terminated-string,那该怎么办呢?我们 自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。比如:

char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};

	
sprintf(s, "%.7s%.7s", a1, a2); // 产生:"ABCDEFGHIJKLMN"

在有些时候,我们希望格式控制字符中指定的长度是动态的,不是静态指定的,sprintf 采用“*”来占用一个本来需要一个指定宽度或精度的常数数字的位置。

sprintf(str,"%*.5d%*.6d",7,a1,6,a2);
sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);

3.利用sprintf()函数的返回值
成功返回打印的字符数

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

int main(int argc, char **argv)

{
    srand(time(0));
    char s[64];
    int offset = 0;
    for (int i = 0; i < 10; i++)
    {
        offset += sprintf(s + offset, "%d, ", rand() % 100);
    }
    s[offset - 1] = '\n'; // 将最后一个逗号换成换行符。
    printf(s);
    return 0;
}

二、snprintf()函数详解
函数原型:

int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...);

函数说明:最多从源串中拷贝 n-1 个字符到目标串中,然后再在后面加一个 ‘\0’。所以如果目标串的大小为 n 的话,将不会溢出。
函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。

特别注意:snprintf()函数的返回值是欲写入的字符串长度,而不是实际写入的字符串长度。

#include <stdio.h>

 

int main(int argc, char **argv)

{
    char test[8];
    int ret = snprintf(test, 5, "1234567890");
    printf("%d|%s\n", ret, test);
    return 0;
}

函数返回值测试:

#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    char str1[10] = {0,};
    char str2[10] = {0,};
    int ret1 = 0, ret2 = 0;
    ret1 = snprintf(str1, sizeof(str1), "%s", "abc");
    ret2 = snprintf(str2, 4, "%s", "aaabbbccc");
    printf("aaabbbccc length=%d\n", strlen("aaabbbccc"));
    printf("str1=%s,ret1=%d\n", str1, ret1);
    printf("str2=%s,ret2=%d\n", str2, ret2);
    return 0;
}

输出结果:
aaabbbccc length=9
str1=abc,ret1=3
str2=aaa,ret2=9

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值