C进阶--字符函数和字符串函数介绍

更多细节参考 cplusplus.com/reference/cstring/

使用方式:

⭕ 求字符串长度

🖌   strlen

函数原型:

size_t strlen ( const char * str );

作用:

获取字符串长度

✨补充:
⭐字符串以  '\0' 作为结束标志, strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )

⭐参数指向的字符串必须要以 '\0' 结束。
⭐注意函数的返回值为size_t ,是无符号的( 易错

strlen函数的使用

#include <stdio.h>
#include <string.h>int main ()
{char buffer[256];printf ("Enter a sentence: ");gets (buffer);printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));return 0;
}

运行结果:

strlen函数模拟实现

🔪 方法一:计数器

size_t my_strlen(const char* str)
{int count = 0;assert(str != NULL);while (*str != '\0'){count++;str++;}return count;
}

🔪 方法二:递归

size_t my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn my_strlen(str + 1) + 1;
}

🔪 方法三:指针-指针

size_t my_strlen(const char* str)
{const char* p = str;while (*str != '\0')str++;return str - p;
}

⭕ 长度不受限制的字符串函数

🖌   strcpy

函数原型:

char * strcpy ( char * destination, const char * source );

函数功能

将源指向的 C 字符串复制到目标指向的数组中

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str1[]="Sample string";char str2[40];char str3[40];strcpy (str2,str1);strcpy (str3,"copy successful");printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);return 0;
}
✨有源字符串必须以 '\0' 结束。
✨会将源字符串中的 '\0' 拷贝到目标空间。
✨目标空间必须足够大,以确保能存放源字符串。
✨目标空间必须可变。

✨strcpy函数返回的是目标空间的起始地址
✨strcpy函数的返回类型的设置是为了实现链式访问

模拟实现:

char* my_strcpy(char*dest, const char* src)
{char* ret = dest;while(*dest++ = *src++);return ret;
}

🖌  strcat

函数原型:

char * strcat ( char * destination, const char * source );

函数功能:

将源字符串的副本追加到目标字符串。目标中的终止空字符被源的第一个字符覆盖,并且在目标中由两者串联形成的新字符串的末尾包含一个空字符。

目的地和来源不得重叠。

⭐ 目标空间必须有足够的大,能容纳下源字符串的内容。
⭐ 目标空间必须可修改。

函数使用:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include <assert.h>int main()
{char str[80];strcpy(str, "these ");strcat(str, "strings ");strcat(str, "are ");strcat(str, "concatenated.");puts(str);return 0;
}

目的地和来源不得重叠。所以不可以自己给自己追加喔(strcat(s,s);绝对不可以喔。🙅‍♀️)

模拟实现:

char* my_strcat(char* dest, char* src)
{assert(dest && src);char* ret = dest;//找目标空间中的\0while (*dest)dest++;//拷贝while (*dest++ = *src++);return ret;
}

🖌   strcmp

函数原型:

int strcmp ( const char * str1, const char * str2 );

函数功能:

此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止空字符。

ps:此函数执行字符的二进制比较。有关考虑特定于区域设置的规则的函数,请参阅 strcoll。

返回值:
第一个字符串大于第二个字符串,则返回大于 0 的数字
第一个字符串等于第二个字符串,则返回 0
第一个字符串小于第二个字符串,则返回小于 0 的数字

函数使用:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char key[] = "apple";char buffer[80];do {printf("Guess my favorite fruit? ");fflush(stdout);//刷新输出缓冲区scanf("%79s", buffer);} while (strcmp(key, buffer) != 0);puts("Correct answer!");return 0;
}

  fflush(stdout);作用:刷新输出缓冲区--更多欢迎进入主页查看文件系统与inode编号 有更详细的介绍

模拟实现:

✍ 代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include <assert.h>int my_strcmp(const char* s1, const char* s2)
{assert(s1 && s2);while (*s1 == *s2){if (*s1 == '\0'){return 0;//相等}s1++;s2++;}//不相等return *s1 - *s2;
}
int main()
{char * s1 = "abcde";char * s2 = "acbde";char * s3 = "abcde";char * s4 = "abbbbb";printf("s1 vs s2 %d\n", my_strcmp(s1, s2));printf("s1 vs s3 %d\n", my_strcmp(s1, s3));printf("s1 vs s4 %d\n", my_strcmp(s1, s4));return 0;
}

📕 运行结果:

⭕ 长度受限制的字符串函数介绍

🖌  strncpy

函数原型:

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

函数功能:

将源的第一个字符数复制到目标。如果在复制 num 个字符之前找到源 C 字符串的末尾(由 null 字符表示),则目标将填充零,直到总共写入 num 个字符为止。

⭐ 如果源长度超过 num,则不会在目标末尾隐式附加空字符。因此,在这种情况下,不应将目标视为以空结尾的 C 字符串(这样读取它会溢出)。

⭐ 目的地和来源不得重叠 

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str1[]= "To be or not to be";char str2[40];char str3[40];/* copy to sized buffer (overflow safe): */strncpy ( str2, str1, sizeof(str2) );/* partial copy (only 5 chars): */strncpy ( str3, str2, 5 );str3[5] = '\0';   /* null character manually added */puts (str1);puts (str2);puts (str3);return 0;
}

运行结果:

模拟实现:

char* my_strncpy(char* destination, const char* source, size_t n)
{char* cp = destination;int i = 0;while (*source && i < n){*cp++ = *source++;i++;}for (int j = i; j < n; j++){*cp++ = 0;}return destination;
}

🖌  strncat

函数原型:

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

函数功能:

将源的第一个数字字符追加到目标,外加一个终止空字符。

如果源中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容。

函数使用:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}

运行结果:

❓  字符串自己给自己追加,如何?
对于strncat函数,它可以在目标字符串中追加源字符串的一部分内容,但不能直接将源字符串追加到自身。

模拟实现:

代码实现:

#include<stdio.h>
#include<assert>
#include<string.h>char* my_strncat(char* dest, const char* src, size_t num) {assert(dest && src);char* ret = dest;/*while (num--) {*dest++ = *src++;}*/while (*dest != '\0') {dest++;}size_t i = 0;for (; src != 0 && i < num; i++) {dest[i] = src[i];}return ret;
}
int main() {char dest[20] = "hahaha";char src[10] = "yyyyyy";my_strncat(dest, src, 2);printf("%s\n", dest);return 0;
}

运行结果:

🖌 strncmp

函数原型:

int strncmp ( const char * str1, const char * str2, size_t num );

函数功能:

比较两个字符串的字符
将 C 字符串 str1 的字符数与 C 字符串 str2 的字符数进行比较。
此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下对,直到字符不同,直到达到终止的空字符,或者直到两个字符串中的 num 字符匹配,以先发生者为准。

返回值:
第一个字符串大于第二个字符串,则返回大于 0 的数字
第一个字符串等于第二个字符串,则返回 0
第一个字符串小于第二个字符串,则返回小于 0 的数字

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}

模拟实现:

int my_strncmp(const char *str1, const char *str2, int n)
{assert(str1 != NULL&&str2 != NULL);while(n--&&*str1 == *str2){str1++;str2++;}return *str1 - *str2;
}

⭕ 字符串查找

🖌 strstr

函数原型:

const char * strstr ( const char * str1, const char * str2 );
char * strstr (char * str1, const char * str2 );

函数功能:查找子字符串

返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回一个空指针。

匹配过程不包括终止空字符,但它到此为止。

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{
//查找出错误的sample并替换为正确的char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");if (pch != NULL)strncpy (pch,"sample",6);puts (str);return 0;
}

运行结果:

模拟实现:

char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = str1;const char* s2 = str2;const char* cur = str1;while (*cur){s1 = cur;s2 = str2;while (*s1 && *s2 && (*s1 == *s2)){s1++;s2++;}if (*s2 == '\0'){return (char*)cur;}cur++;}return NULL;//找不到
}

🖌   strtok

函数原型:

char * strtok ( char * str, const char * delimiters );

函数功能:

将字符串拆分为以标记分开的字符串。
此函数的一系列调用将 str 拆分为标记,这些标记是由分隔符中的任何字符分隔的连续字符序列。

⭐ 在第一次调用时,该函数需要一个 C 字符串作为 str 的参数,其第一个字符用作扫描令牌的起始位置。在后续调用中,该函数需要一个空指针,并使用最后一个令牌末尾之后的位置作为扫描的新起始位置。

⭐ 为了确定标记的开头和结尾,该函数首先从起始位置扫描分隔符中未包含的第一个字符(该字符将成为标记的开头)。然后从令牌的开头开始扫描分隔符中包含的第一个字符,该字符将成为令牌的末尾。如果找到终止空字符,扫描也会停止。

⭐ 令牌的此结尾将自动替换为空字符,并且令牌的开头由函数返回。

一旦在对 strtok 的调用中找到 str 的终止空字符,则对此函数的所有后续调用(以空指针作为第一个参数)都将返回空指针。

⭐找到最后一个令牌的点由要在下一次调用中使用的函数在内部保留(不需要特定的库实现来避免数据争用)。

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}

模拟实现:

char* my_strtok(char* strToken, const char* strDelimit)
{char* str1 = strToken;char* temp = NULL;char* str2 = (char*)strDelimit;static char* pos = NULL;if (str1 != NULL){while (*str1){str2 = (char*)strDelimit;while (*str2 != '\0'){if ((*str1 == *str2)){if (*(str1 + 1) == '\0')pos = NULL;elsepos = str1;*str1 = '\0';return strToken;}str2++;}str1++;}}else{if (pos != NULL){str1 = pos + 1;temp = pos + 1;while (*str1){str2 = (char*)strDelimit;while (*str2 != '\0'){if ((*str1 == *str2)){pos = str1;*str1 = '\0';return temp;}str2++;}str1++;}pos = NULL;return temp;}	}return NULL;
}

⭕ 错误信息报告

🖌  strerror

函数原型:

char * strerror ( int errnum );

函数功能:获得一个指向错误信息字符串的字符指针

⭐ 解释 errnum 的值,生成一个字符串,其中包含描述错误条件的消息,就像由库的函数设置为 errno 一样。

⭐ 返回的指针指向静态分配的字符串,程序不应修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。

⭐ strerror 生成的错误字符串可能特定于每个系统和库实现。

函数使用:

#include <stdio.h>
#include <string.h>
#include <errno.h>int main ()
{FILE * pFile;pFile = fopen ("unexist.ent","r");if (pFile == NULL)printf ("Error opening file unexist.ent: %s\n",strerror(errno));return 0;
}

 ⭕ 内存操作函数

 🖌 memcpy

函数原型:

void * memcpy ( void * destination, const void * source, size_t num );


函数功能:复制内存块

将字节数的值从源指向的位置直接复制到目标指向的内存块。

⭐ 源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

⭐ 该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。

⭐ 为避免溢出,目标和源参数指向的数组大小应至少为字节数,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)。

函数使用:

#include <stdio.h>
#include <string.h>struct {char name[40];int age;
} person, person_copy;int main ()
{char myname[] = "Pierre de Fermat";/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)+1 );person.age = 46;/* using memcpy to copy structure: */memcpy ( &person_copy, &person, sizeof(person) );printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );return 0;
}


模拟实现:

void* my_memcpy(void* dest, const void* src, size_t count)
{assert(dest && src);void* ret = dest;while (count--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}

 🖌  memmove

函数原型:

void * memmove ( void * destination, const void * source, size_t num );


函数功能:

移动内存块
将字节数的值从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样,允许目标和源重叠。

⭐ 源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

⭐ 该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。

⭐ 为避免溢出,目标参数和源参数指向的数组的大小应至少为字节数。

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str[] = "memmove can be very useful......";memmove (str+20,str+15,11);puts (str);return 0;
}


模拟实现:

void* my_memmove(void* dest, const void*src, size_t count)
{assert(dest && src);void* ret = dest;//1if (dest < src){//前->后while (count--){*(char*)dest = *(char*)(src);dest = (char*)dest + 1;src = (char*)src + 1;}}else{//后->前while (count--){*((char*)dest+count) = *((char*)src + count);}}return ret;
}

 🖌  memcmp

函数原型:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );


函数功能:比较两个内存块

将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的第一个字节数进行比较,如果它们都匹配,则返回零,如果不匹配,则返回一个不同于零的值,表示哪个更大。

请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n=memcmp ( buffer1, buffer2, sizeof(buffer1) );if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);return 0;
}


模拟实现:

🔪 方式一:

int my_memcmp1(const void* p1, const void* p2, size_t count)//方法1
{assert(p1);assert(p2);char* dest = (char*)p1;char* src = (char*)p2;while (count && (*dest == *src)){count--;dest++;src++;}if (count == 0)return 0;return *dest - *src;
}

🔪 方式二:

int my_memcmp2(const void* p1, const void* p2, size_t count)//方法2
{assert(p1);assert(p2);int ret = 0;char* dest = (char*)p1;char* src = (char*)p2;while (count && (!(ret = (*dest - *src)))){dest++;src++;count--;}if (ret > 0){return 1;}else if (ret < 0){return -1;}return 0;}

 🖌   memset

函数原型:

void * memset ( void * ptr, int value, size_t num );


函数功能:填充内存块

将 ptr 指向的内存块的第一个字节数设置为指定值(解释为无符号字符)。

函数使用:

#include <stdio.h>
#include <string.h>int main ()
{char str[] = "almost every programmer should know memset!";memset (str,'-',6);puts (str);return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/93700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++算法 —— 动态规划(8)01背包问题

文章目录 1、动规思路简介2、模版题&#xff1a;01背包第一问第二问优化 3、分割等和子集4、目标和5、最后一块石头的重量Ⅱ 背包问题需要读者先明白动态规划是什么&#xff0c;理解动规的思路&#xff0c;并不能给刚接触动规的人学习。所以最好是看了之前的动规博客&#xff0…

【CFD小工坊】浅水方程的离散及求解方法

【CFD小工坊】浅水方程的离散及求解方法 前言基于有限体积法的方程离散界面通量与源项计算干-湿网格的处理数值离散的稳定性条件参考文献 前言 我们模型的控制方程&#xff0c;即浅水方程组的表达式如下&#xff1a; ∂ U ∂ t ∂ E ( U ) ∂ x ∂ G ( U ) ∂ y S ( U ) U…

C++list模拟实现

list模拟实现 1.链表结点2.类模板基本框架3.构造4.插入普通迭代器实现4.1尾插4.2普通迭代器实现4.3对比list和vector的iterator4.4迭代器的价值4.5insert4.6尾插头插复用写法 5.删除erase5.1erase5.2尾删头删复用写法 6.析构emptysizeclear6.1clear6.2size6.3 empty6.4 析构 7.…

<C++>类和对象-下

目录 一、构造函数的初始化 1. 构造函数体赋值 2. 初始化列表 2.1 概念 2.2 隐式类型转换式构造 2.3 explicit关键字 二、static静态成员 1. 概念 2. 特性 三、友元 1. 友元函数 2.友元类 四、内部类 1. 概念 五、匿名对象 1. const引用匿名对象 2. 匿名对象的隐式类型转换 总…

获取网卡上的IP、网关及DNS信息,获取最佳路由,遍历路由表中的条目(附源码)

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

Linux进程控制

文章目录 前言一、进程创建1、fork函数2、写时拷贝3、子进程从哪里开始执行父进程代码 二、进程终止1、进程终止时&#xff0c;操作系统做了什么2、进程终止的常见方式2.1 main函数退出码 3、在代码中终止进程3.1 使用return语句终止进程3.2 使用exit函数终止进程3.3 使用_exit…

c#设计模式-结构型模式 之 组合模式

&#x1f680;简介 组合模式又名部分整体模式&#xff0c;是一种 结构型设计模式 &#xff0c;是用于把一组相似的对象当作一个 单一的对象 。组合模式 依据树形结构来组合对象 &#xff0c;用来表示部分以及整体层&#xff0c;它可以让你将对象组合成树形结构&#xff0c;并且…

leetCode 45.跳跃游戏 II 贪心算法

45. 跳跃游戏 II - 力扣&#xff08;LeetCode&#xff09; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 &…

大语言模型之十四-PEFT的LoRA

在《大语言模型之七- Llama-2单GPU微调SFT》和《大语言模型之十三 LLama2中文推理》中我们都提到了LoRA&#xff08;低秩分解&#xff09;方法&#xff0c;之所以用低秩分解进行参数的优化的原因是为了减少计算资源。 我们以《大语言模型之四-LlaMA-2从模型到应用》一文中的图…

已解决 Bug——IndexError: index 3 is out of bounds for axis 0 with size 3问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

格点数据可视化(美国站点的日降雨数据)

获取美国站点的日降雨量的格点数据&#xff0c;并且可视化 导入模块 from datetime import datetime, timedelta from urllib.request import urlopenimport cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.colors as mcolors import matplotli…

JAVA学习(2)-全网最详细~

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

选择排序算法:简单但有效的排序方法

在计算机科学中&#xff0c;排序算法是基础且重要的主题之一。选择排序&#xff08;Selection Sort&#xff09;是其中一个简单但非常有用的排序算法。本文将详细介绍选择排序的原理和步骤&#xff0c;并提供Java语言的实现示例。 选择排序的原理 选择排序的核心思想是不断地从…

CCF CSP认证 历年题目自练 Day20

题目一 试题编号&#xff1a; 201903-1 试题名称&#xff1a; 小中大 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述&#xff1a; 题目分析&#xff08;个人理解&#xff09; 常规题目&#xff0c;先看输入&#xff0c;第一行输入n表示有多少数字&am…

axb_2019_brop64

axb_2019_brop64 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)64位&#xff0c;只开了NX __int64 repeater() {size_t v1; // raxchar s[208]; // [rsp0h] [rbp-D0h] BYREFprintf("…

小谈设计模式(15)—观察者模式

小谈设计模式&#xff08;15&#xff09;—观察者模式 专栏介绍专栏地址专栏介绍 观察者模式核心思想主要角色Subject&#xff08;被观察者&#xff09;ConcreteSubject&#xff08;具体被观察者&#xff09;Observer&#xff08;观察者&#xff09;ConcreteObserver&#xff0…

HTML的学习 Day02(列表、表格、表单)

文章目录 一、列表列表主要分为以下三种类型&#xff1a;1. 无序列表&#xff08;Unordered List&#xff09;&#xff1a;2. 有序列表&#xff08;Ordered List&#xff09;&#xff1a;将有序列表的数字改为字母或自定义内容li.../li 列表项标签中value属性&#xff0c;制定列…

【简单的留言墙】HTML+CSS+JavaScript

目标&#xff1a;做一个简单的留言墙 1.首先我们用HTML的一些标签&#xff0c;初步构造区域 样式。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>留言墙</title><style>/* ...... */ …

FFmpeg 命令:从入门到精通 | ffmpeg filter(过滤器 / 滤镜)

FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg filter&#xff08;过滤器 / 滤镜&#xff09; FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg filter&#xff08;过滤器 / 滤镜&#xff09;ffmpeg fliter 基本内置变量视频裁剪文字水印图片水印画中画视频多宫格处理 FFmpeg 命…

使用 cURL 发送 HTTP 请求: 深入探讨与示例

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…