strcpy、strncpy、strncpy_s和snprintf

本文详细介绍了C语言中用于字符串拷贝的四个函数:strcpy、strncpy、strncpy_s和snprintf。其中,strcpy不检查目标缓冲区大小,可能导致溢出;strncpy按指定长度复制,但可能不添加终止符;strncpy_s考虑了目标缓冲区大小,避免溢出,但不是标准库函数;snprintf则能安全地格式化字符串并复制到目标缓冲区,根据缓冲区大小决定复制内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、strcpy

原型声明:
extern char *strcpy(char* dest, const char *src);

依据源串的\0作为结束判断的,不会检查需要拷贝的缓冲区的大小,如果目标空间不够,就有溢出问题。


2、strncpy

原型

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

复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_t的值决定,返回指向dest的指针。如果遇到空字符('\0'),则空字符后面为原来的字符

代码如下:

dest[]="Hell99iam!";
src[]="abc\0def";
strncpy(dest,src,5);

此时,dest区域是这样的:'a','b','c','\0','\0','9','i','a','m','!'

而非这样:'a','b','c','\0','\0','\0','\0','\0','\0','\0'

'\0','\0'并不是添加在'!'的后面。可以用for循环输出每个元素的ascii来确定。

strncpy是字符串拷贝推荐的用法


3、strncpy_s

原型:
errno_t strncpy_s(
char *strDest,
size_t numberOfElements,
const char *strSource,
size_t count
);

参数numberOfElements表明dest中的字节数,防止目标指针dest中的空间不够,同时返回值改成返回错误代码,而不是返回char*。

会在字符串结束处填补一个空字符。

count参数需要小于目标缓冲区大小。

如果情况如下代码:

char dst[5];
strncpy_s(dst, sizeof(dst), "a long string", 5);

表示使用strncpy_s 拷贝5个字节到dst缓冲区,使得没用多余空间给空字符结束符,填补空字符时会溢出,并调用异常处理句柄。

需要补空字符时使用 _TRUNCATE 或者 (size – 1)

代码如下:

char dst[5];
strncpy_s(dst, sizeof(dst), "a long string", _TRUNCATE);
strncpy_s(dst, sizeof(dst), "a long string", sizeof(dst)-1);

跟strncpy不一样,当count参数比源字符串长时,strncpy_s 不会一直补空字符到指定长度。

如果源地址字符串和目标地址字符串重叠,则结果未定义。

_s版本函数并不是标准库,不推荐使用

4、snprintf

原型:

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

将可变个参数(...)按照format格式化成字符串,然后将其复制到str中

(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');

(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。

#include <stdio.h>
int main () {
  char a[16];
  size_t i;
  i = snprintf(a, 13, "%012d", 12345);  // 第 1 种情况
  printf("i = %lu, a = %s\n", i, a);    // 输出:i = 12, a = 000000012345
 
  i = snprintf(a, 9, "%012d", 12345);   // 第 2 种情况
  printf("i = %lu, a = %s\n", i, a);    // 输出:i = 12, a = 00000001
  return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值