C语言常用函数-1(sprintf & memset & strncpy)

一. sprintf

原型:

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

功能
把格式化的数据写入某个字符串缓冲区

参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]…:可选参数,可以是任何类型的数据。
返回值:字符串长度(strlen)

  1. sprintf函数的功能与printf函数的功能基本一样,只是它把结果输出到指定的字符串中了。
    sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。
  2. sprintf的第一个参数是目的字符串,如果不指定这个参数,执行过程中出现 "该程序产生非法操作,即将被关闭…"的提示。因为C语言在进行字符串操作时不检查字符串的空间是否够大,所以可能会出现数组越界而导致程序崩溃的问题。即使碰巧,程序没有出错,也不要这么用,因为早晚会出错。所以一定要在调用sprintf之前分配足够大的空间给buffer
  3. sprintf 是个变参函数,除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:格式化字符串上。
    printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串格式化数字字符串
  4. sprintf 最常见的应用之一是把整数打印到字符串中。

例如,把整数123 打印成一个字符串保存在s 中:

sprintf(s, "%d", 123); //产生"123"

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

sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"

当然也可以左对齐:

sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"

也可以按照16 进制打印:

sprintf(s, "%8x", 4567); //小写16 进制,宽度占8个位置,右对齐
sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8个位置,左对齐

这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。

sprintf(s, "%08X", 4567); //产生:"000011D7"

使用sprintf 的常见问题:

【缓冲区溢出】
第一个参数的长度太短了。当然也可能是后面的参数的问题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。

【忘记第一个参数】
用printf 用得太惯了。

【变参对应出问题】
通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位。尤其是对应”*”的那些参数,不要把一个整数对应一个”%s”。

二. memset

每种类型的变量都有各自的初始化方法,memset() 函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行初始化工作。它是直接操作内存空间,mem即“内存”(memory)的意思。

原型:

void *memset(void *s, int c, unsigned long n);

功能
将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。

memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。

memset 一般使用“0”初始化内存单元,而且通常是给数组结构体进行初始化。一般的变量如 char、int、float、double 等类型的变量直接初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦。

当然,数组也可以直接进行初始化,但 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。

这时有人会问:“字符串数组不是最好用’\0’进行初始化吗?那么可以用 memset 给字符串数组进行初始化吗?也就是说参数 c 可以赋值为’\0’吗?”

可以的。虽然参数 c 要求是一个整数,但是整型和字符型是互通的。但是赋值为 ‘\0’ 和 0 是等价的,因为字符 ‘\0’ 在内存中就是 0。所以在 memset 中初始化为 0 也具有结束标志符 ‘\0’ 的作用,所以通常我们就写“0”。

memset 函数的第三个参数 n 的值一般用 sizeof() 获取,这样比较专业。注意,如果是对指针变量所指向的内存单元进行清零初始化,那么一定要先对这个指针变量进行初始化,即一定要先让它指向某个有效的地址。而且用memset给指针变量如p所指向的内存单元进行初始化时,n 千万别写成 sizeof (p),这是新手经常会犯的错误。因为 p 是指针变量,不管 p 指向什么类型的变量,sizeof (p)的值都是 4。

下面写一个程序:

# include <stdio.h>
# include <string.h>
int main(void)
{
  int i;  //循环变量
  char str[10];
  char *p = str;
  memset(str, 0, sizeof(str));  //只能写sizeof(str), 不能写sizeof(p)
  for (i=0; i<10; ++i)
  {
  printf("%d\x20", str[i]);
  }
  printf("\n");
  return 0;
}

根据memset函数的不同,输出结果也不同,分为以下几种情况:

memset(p, 0, sizeof(p));  //地址的大小都是4字节
0 0 0 0 -52 -52 -52 -52 -52 -52
memset(p, 0, sizeof(*p));  //*p表示的是一个字符变量, 只有一字节
0 -52 -52 -52 -52 -52 -52 -52 -52 -52
memset(p, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0
memset(str, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0
memset(p, 0, 10);  //直接写10也行, 但不专业
0 0 0 0 0 0 0 0 0 0

三. strncpy

原型:

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

功能
把src 所指向的字符串复制到dest,最多复制n个字符。当src的长度小于n时,dest的剩余部分将用空字节填充。

参数:
dest : 指向用于存储复制内容的目标数组
src : 要复制的字符串
n: 要从源中复制的字符数

返回值:
该函数返回最终复制的字符串

实例:

#include <stdio.h>
#include <string.h>

int main()
{
 char src[40];
 char dest[12];
 memset(dest,'\0',sizeof(dest));
 strcpy(src,"This is runoob.com");
 strncpy(dest,src,10);
 printf("最终的目标字符串:%s\n",dest);
 
 return (0);
}
最终的目标字符串:This is ru
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值