解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

简介: 解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

今天又来继续我们的字符串函数的文章,这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。

strchr

 

strchr  是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现  strchr  函数的示例:

解析  strchr  函数:

 

 


#include <stdio.h>
 
// 解析 strchr 函数
void parse_strchr() {
    const char *string = "Hello, World!";
    char target = 'l';
 
    // 使用 strchr 函数查找字符
    const char *found = strchr(string, target);
 
    if (found != NULL) {
        printf("Character '%c' found at index: %zu\n", target, found - string);
    } else {
        printf("Character '%c' not found in string\n", target);
    }
}
 
int main() {
    parse_strchr();
    return 0;
}
 

在上述示例中,我们定义了一个字符串  string  和要查找的目标字符  target 。然后,使用  strchr  函数在字符串中查找目标字符,并将找到的位置存储在  found  变量中。根据  found  是否为  NULL ,我们输出相应的结果。


 

模拟实现  strchr  函数:

 

 

#include <stdio.h>
 
// 模拟实现 strchr 函数
const char * my_strchr(const char * string, char target)
{
  for (; *string  != '\0'; string++)
  {
    if (*string == target)
    {
      return string;
    }
  }
  return NULL;
}
 
int main() {
  const char * string = "Hello, World!";
  char target = 'l';
 
  // 使用模拟的 my_strchr 函数查找字符
  const char * found = my_strchr(string, target);
 
  if (found != NULL)
  {
    printf("Character'%c'found at index:%zu\n", target, found - string);
  }
  else 
  {
    printf("Character'%c' not found in string\n", target);
  }
 
  return 0;
}


 

 

在模拟实现中,我们使用一个循环遍历字符串中的每个字符。如果找到了与目标字符匹配的字符,就返回该字符的地址。如果循环结束后仍未找到,返回  NULL 。

这两种方法(解析和模拟实现)都可以用来在字符串中查找特定字符。使用标准库中的  strchr  函数通常更方便和可靠,但模拟实现可以帮助你更好地理解其工作原理。


strtok

strtok  是一个用于分割字符串的函数。它根据指定的分隔符将字符串分割成多个部分,并可以逐个提取这些部分。


下面是模拟和解析  strtok  函数的示例:

解析  strtok  函数:

#include <stdio.h>
#include <string.h>
 
// 解析 strtok 函数
void parse_strtok() {
  char string[] = "apple,banana,cherry";
  char delimiter[] = ",";
 
  // 使用 strtok 函数分割字符串
  char * token = strtok(string, delimiter);
  while (token != NULL) {
    printf("%s\n", token);
    token = strtok(NULL, delimiter);
  }
}
 
int main() {
  parse_strtok();
  return 0;
}


 

在这个示例中,我们直接使用了标准库中的  strtok  函数来分割字符串,并打印每个部分。

 

模拟  strtok  函数:

 

 

#include <stdio.h>
#include <string.h>
 
// 模拟 strtok 函数
char * my_strtok(char * str, const char * delimiter) 
{
  static char* token = NULL;
  if (str  == NULL) {
    return NULL;
  }
  while (1)
  {
    // 查找下一个分隔符的位置
    char* next = strstr(str, delimiter);
 
    // 如果找到分隔符
    if (next != NULL) {
      *next = '\n';
    }
    else if (next == NULL)
      break;
  }
  token = str;
 
  return token;
}
 
int main() {
  char string[] = "apple,banana,cherry";
  char delimiter[] = ",";
 
  // 使用模拟的 my_strtok 函数分割字符串
  char * token = my_strtok(string, delimiter);
  while (token != NULL) 
  {
    printf("%s\n", token);
    token = my_strtok(NULL, delimiter);
  }
 
  return 0;
}
 


在上述示例中,我们模拟了  strtok  函数的行为。通过使用  strstr  函数查找分隔符的位置,并将其设置为字符串的换行符。然后,返回找到的下一个部分的指针。


无论是模拟还是直接使用  strtok ,它们的基本原理都是根据指定的分隔符将字符串分割成多个部分。需要注意的是, strtok  函数会修改原始字符串,并且在多次调用时需要注意处理  NULL  指针的情况。


sprintf和sscanf


sprintf 是一个变参函数,用于格式化字符串并将结果写入到指定的缓冲区中,其函数声明为 int sprintf(char *buffer, const char *format, ...) 。下面是对各参数的详细解释:

-  buffer :是 char 类型的指针,指向要写入的字符串的指针。

-  format :格式化字符串,即在程序中指定的格式。

-  argument :可选参数,可以为任意类型的数据,可以有一个或多个参数。

该函数的返回值是写入到缓冲区中的字符数,不包括字符串结尾的空字符 \0 。下面是一些常见的用法示例:

 

- 格式化数字字符串:

 

 

// 把整数123打印成一个字符串保存在s中
sprintf(s, "%d", 123); 
// 产生 "123"


- 控制浮点数打印格式:

 

 

// 保留小数点后6位数字
sprintf(s, "%f", 3.1415926); 
// 产生 "3.141593"
 



- 连接字符串:

// 连接字符串
char *who = "I"; 
char *whom = "52PHP"; 
sprintf(s, "%s love %s.", who, whom); 
// 产生 "I love 52PHP. " 

- 打印整数和浮点数时可以指定宽度:

 

 

// 指定宽度
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 函数时,应确保格式化字符串和变参列表的匹配,并确保缓冲区的大小足够容纳输出结果。


sscanf 函数是一个用于从字符串中读取数据的 C 语言函数,与 scanf 函数类似,但是它的输入源是一个字符串而不是标准输入。 sscanf 函数的声明如下:


int sscanf(const char *str, const char *format, ...)

参数说明:

-  str :这是 C 字符串,是函数检索数据的源。

-  format :这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符 。

-  ... :这是可变参数,为对应的附加参数所指向的数据指定一个不同于整型(针对 d、i 和 n)、无符号整型(针对 o、u 和 x)或浮点型(针对 e、f 和 g)的大小。

该函数会将参数 str 的字符串根据参数 format 字符串来转换并格式化数据,转换后的结果存于对应的参数内。返回值为成功匹配和赋值的个数,如果没有成功匹配的项,则返回 0 。

下面是一些常见的用法示例:

- 从字符串中读取一个字符:

char c;
sscanf("Hello", "%c", &c);

- 从字符串中读取一个整数:

 

 

1. int i;
2. sscanf("12345", "%d", &i);
3.

- 从字符串中读取一个浮点数:

 

 

float f;
sscanf("3.1415", "%f", &f);


- 从字符串中读取多个数据:

 

 

int i, j;
char s[50];
sscanf("12 56", "%d %s", &i, s, &j);
 

需要注意的是, sscanf 函数在字符串中读取数据时不会进行边界检查,可能会导致缓冲区溢出或其他问题。因此,在使用 sprintf 函数时,应确保字符串中的数据格式与 format 字符串中的格式说明符相匹配,并确保缓冲区的大小足够容纳读取的数据。


sprintf和sscanf的模拟实现太复杂就不模拟了。


文章已到末尾,希望多多支持。


目录
相关文章
|
Linux C语言 开发者
深入解析Linux环境下的scanf()、sscanf()和fscanf()函数
在C语言中,`scanf()`、`sscanf()`和`fscanf()`是用于输入的三个常用函数。它们允许开发者从标准输入、字符串和文件中按照指定的格式读取数据。在Linux环境下,这些函数被广泛用于处理各种输入。本文将详细介绍这三个函数的用法,包括格式化字符串的语法和一些常见的使用场景。
1515 1
解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)
解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)
362 0
|
C语言
字符函数和字符串函数解析及模拟实现
字符函数和字符串函数解析及模拟实现
218 0
|
C语言 C++
C语言常见字符串函数解析(上)
C语言常见字符串函数解析(上)
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
872 140
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
528 2
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1367 29
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
549 4
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

推荐镜像

更多
  • DNS