当前位置: 首页 > ops >正文

strncpy 函数使用及其模拟实现

目录

一、strncpy 函数函数原型

1、功能描述

2、具体行为

3、注意事项

示例

二、strncpy 函数的模拟实现

关键点解析

测试用例

Test1: Hello烫烫烫...


一、strncpy 函数函数原型

char *strncpy(char *destination, const char *source, size_t num);

1、功能描述

strncpy 函数用于将源字符串(source)的前 num 个字符复制到目标空间(destination)中。

2、具体行为

  1. 正常复制:复制源字符串的前 num 个字符到目标空间。

  2. 源字符串较短时:如果源字符串长度小于 num(即遇到 null 终止符'\0'),则:

    • 然后在目标空间中用 null 字符('\0')填充剩余空间,直到总共写入 num 个字符

    • 先复制源字符串所有内容(包括终止符)

  3. 源字符串较长时如果源字符串前 num 个字符中没有 null 终止符,则不会自动添加终止符

3、注意事项

  • 目标空间必须足够大,至少能容纳 num 个字符

  • 与 strcpy 不同,strncpy 不保证目标字符串以 null 终止(当源字符串长度 ≥ num 时)

  • 如果 num 大于源字符串长度,会浪费空间填充 null 字符

  • 使用时通常需要手动确保字符串终止:destination[num-1] = '\0'

示例

char dest[10];
strncpy(dest, "hello", 10);  // 复制"hello"并填充5个'\0'
strncpy(dest, "longer string", 5);  // 只复制"longe",不会自动添加'\0'
dest[4] = '\0';  // 需要手动终止

二、strncpy 函数的模拟实现

下面是一个完整的 strncpy 函数模拟实现,包含详细注释和边界条件处理:

#include <stddef.h>  // for size_t/*** @brief 模拟实现 strncpy 函数* @param dest 目标字符串地址* @param src 源字符串地址* @param n 要复制的字符数* @return 目标字符串地址*/
char *my_strncpy(char *dest, const char *src, size_t n) {// 记录起始地址用于返回char *start = dest;// 1. 复制字符直到复制完n个字符或遇到src的终止符while (n > 0 && *src != '\0') {*dest++ = *src++;n--;}// 2. 如果n还有剩余,用'\0'填充剩余空间while (n > 0) {*dest++ = '\0';n--;}return start;
}

关键点解析

  1. 参数处理

    • 使用 const char* 保证源字符串不被修改

    • 使用 size_t 类型表示字符数,与标准库一致

  2. 复制过程

    • 第一个 while 循环负责从源字符串复制字符

    • 第二个 while 循环负责填充剩余的 null 字符

  3. 边界条件

    • 正确处理 n=0 的情况

    • 正确处理 src 长度小于 n 的情况

    • 正确处理 src 长度大于等于 n 的情况

  4. 返回值:返回目标字符串起始地址,与标准库行为一致

测试用例

#include <stdio.h>
#include <string.h>int main() {char dest[20];// 测试1: 正常情况my_strncpy(dest, "Hello", 5);printf("Test1: %s\n", dest);  // 应输出 "Hello"// 测试2: 源字符串短于nmemset(dest, '#', 20);  // 填充非零值my_strncpy(dest, "Hi", 5);printf("Test2: %s\n", dest);  // 应输出 "Hi" 后跟3个不可见'\0'// 测试3: 源字符串长于nmy_strncpy(dest, "TooLongString", 5);dest[5] = '\0';  // 手动终止printf("Test3: %s\n", dest);  // 应输出 "TooLo"// 测试4: n=0my_strncpy(dest, "Hello", 0);printf("Test4: %s\n", dest);  // 应无变化return 0;
}

        这个实现完整模拟了标准库 strncpy 的所有行为特征,包括填充 null 字符和不自动终止字符串的特性。

Test1: Hello烫烫烫...

问题原因

  1. my_strncpy 复制了5个字符"H","e","l","l","o"到dest

  2. 没有自动添加字符串终止符'\0'

  3. printf 打印时找不到终止符,继续读取内存直到遇到随机'\0',导致打印出后面内存中的随机内容(显示为"烫烫烫")

http://www.xdnf.cn/news/18270.html

相关文章:

  • 为什么我的UI界面会突然卡顿,失去响应
  • 安装使用Conda
  • pyqt 的自动滚动区QScrollArea
  • Rust 入门 包 (二十一)
  • Ubuntu 虚拟显示器自动控制服务设置(有无显示器的切换)
  • 华为数通认证学习
  • 微算法科技(NASDAQ: MLGO)引入高级区块链DSR算法:重塑区块链网络安全新范式
  • K8S-Configmap资源
  • C++中的 Eigen库使用
  • 数据库DML语言(增、删、改)
  • oracle服务器导入dmp文件
  • Causal-Copilot: An Autonomous Causal Analysis Agent 论文解读
  • 栈的概念(韦东山学习笔记)
  • C#APP.Config配置文件解析
  • Java内功修炼(2)——线程安全三剑客:synchronized、volatile与wait/notify
  • 5.4 4pnpm 使用介绍
  • kotlin 协程笔记
  • AI 创业公司分析报告:RealRoots
  • 0基础安卓逆向原理与实践:第2章:编程基础与工具链
  • 使用PCL读取PCD点云文件
  • Pandas 数据处理核心操作:合并、替换、统计与分组
  • 分贝单位全指南:从 dB 到 dBm、dBc
  • 深入解析EventPoller:Disruptor的轮询式事件处理机制
  • k8s笔记01
  • 服务器硬盘进行分区和挂载
  • SLAM文献之-Globally Consistent and Tightly Coupled 3D LiDAR Inertial Mapping
  • AI +金融 = 七大核心维度+ 落地典型困难
  • 【Golang实战】Go Module 双段 require 配置深度解析
  • Lecture 5 GPUs课程笔记
  • C语言---编译的最小单位---令牌(Token)