C语言:几种字符串常用的API
字符串的常用操作
C 语言的标准库 <string.h>
提供了很多用于处理字符串的函数。
1. strlen
- 计算字符串长度
size_t strlen(const char *str);
- 功能:计算字符串
str
的长度,不包含字符串结束符'\0'
。
2.strcpy
- 复制字符串
char *strcpy(char *dest, const char *src);
- 功能:表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello";char dest[10];strcpy(dest, src);printf("复制后的字符串: %s\n", dest);return 0;
}
#include <stdio.h>
#include <assert.h>// 自定义的字符串复制函数
char* myStrcpy(char *des,char *src)
{assert(des!=NULL&&src!=NULL); //断言char *bak=des;while(*src!='\0'){*des=*src;des++;src++;}*des='\0';return bak;
}char* myStrcpy2(char *des,char *src)
{if(des==NULL||src==NULL){return NULL;}char *bak=des;while(*src!='\0'){*des++=*src++;}*des='\0';return bak;
}char* myStrcpy3(char *des,char *src)
{if(des==NULL||src==NULL){return NULL;}char *bak=des;while((*des++=*src++)!='\0');*des='\0';return bak;
}int main(){char str[128]={'\0'};char *p="diqizhangzifuchuan";myStrcpy(str,p);puts(str);return 0;}
代码详细分析
1. myStrcpy
函数
char* myStrcpy(char *des, char *src)
{assert(des!=NULL && src!=NULL); // 断言char *bak = des;while (*src != '\0') {*des = *src;des++;src++;}*des = '\0';return bak;
}
- 断言检查:使用
assert
函数检查des
和src
指针是否为NULL
。如果为NULL
,程序会触发断言错误并终止。 - 复制过程:通过
while
循环逐个字符地将src
指向的字符串复制到des
指向的内存中,直到遇到字符串结束符'\0'
。 - 添加结束符:复制完成后,手动在
des
末尾添加字符串结束符'\0'
。 - 返回值:返回指向目标字符串起始位置的指针。
2. myStrcpy2
函数
char* myStrcpy2(char *des, char *src)
{if (des == NULL || src == NULL) {return NULL;}char *bak = des;while (*src != '\0') {*des++ = *src++;}*des = '\0';return bak;
}
- 空指针检查:使用
if
语句检查des
和src
指针是否为NULL
,如果是则返回NULL
。 - 复制过程:使用
*des++ = *src++;
语句同时完成字符复制和指针移动。 - 添加结束符:复制完成后,手动在
des
末尾添加字符串结束符'\0'
。 - 返回值:返回指向目标字符串起始位置的指针。
3. myStrcpy3
函数
char* myStrcpy3(char *des, char *src)
{if (des == NULL || src == NULL) {return NULL;}char *bak = des;while ((*des++ = *src++) != '\0');*des = '\0';return bak;
}
- 空指针检查:使用
if
语句检查des
和src
指针是否为NULL
,如果是则返回NULL
。 - 复制过程:使用
while ((*des++ = *src++) != '\0');
语句在一个语句中完成字符复制、指针移动和循环条件判断。 - 添加结束符:由于
while
循环结束时,des
已经指向了字符串结束符的下一个位置,所以需要手动在des
末尾添加字符串结束符'\0'
。 - 返回值:返回指向目标字符串起始位置的指针。
myStrcpy
函数,myStrcpy2
函数,myStrcpy3
函数 实现功能一样
3. strncpy
- 复制指定长度的字符串
char *strncpy(char *dest, const char *src, size_t n);
- 功能:将字符串
src
的前n
个字符复制到dest
中。如果src
的长度小于n
,则在dest
后面填充'\0'
直到达到n
个字符;如果src
的长度大于等于n
,则不会自动添加'\0'
。 - 示例:
#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello, World!";char dest[5];strncpy(dest, src, 4);dest[4] = '\0'; // 手动添加字符串结束符printf("复制后的字符串: %s\n", dest);return 0;
}
原代码尝试实现一个自定义的 myStrncpy
函数,其功能类似标准库中的 strncpy
函数,用于将源字符串的最多 count
个字符复制到目标字符串中。若源字符串长度小于 count
,则用 '\0'
填充目标字符串剩余的空间。
#include <stdio.h>char* myStrncpy(char *des, char *src, int count)
{if (des == NULL || src == NULL) {return NULL;}char *bak = des;// 复制最多 count 个字符while (*src != '\0' && count > 0) {*des = *src;des++;src++;count--;}// 如果 count 还有剩余,填充 '\0'while (count > 0) {*des = '\0';des++;count--;}return bak;
}int main(){char str[128]={'\0'};char *p="diqizhangzifuchuan";myStrncpy(str,p,8);puts(str);return 0;}
原代码逐行分析
#include <stdio.h>char* myStrncpy(char *des, char *src, int count)
{if(des == NULL || src == NULL) {return NULL;}
- 包含
<stdio.h>
头文件,为后续使用输入输出函数(如puts
)做准备。 - 定义
myStrncpy
函数,它接收三个参数:des
是指向目标字符串的指针,src
是指向源字符串的指针,count
表示要复制的最大字符数。 - 首先检查
des
和src
是否为NULL
,若其中任意一个为NULL
,则函数返回NULL
,避免对空指针进行操作。
char *bak = des;while(*src != '\0' && count > 0) {*des++ = *src++;count--;}
- 创建一个临时指针
bak
并初始化为des
,用于保存目标字符串的起始地址,方便后续返回。 - 使用
while
循环进行字符复制操作,条件是源字符串未结束(*src != '\0'
)且还未达到要复制的最大字符数(count > 0
)。在循环中,将源字符串当前字符复制到目标字符串当前位置,然后两个指针都向后移动一位,同时count
减 1。
if(count > 0) {while(count > 0) {count--;*des = '\0';}return des;}
- 当
while
循环结束后,检查count
是否大于 0。若大于 0,说明源字符串已经复制完,但还未达到要复制的最大字符数,此时需要用'\0'
填充目标字符串剩余的空间。 - 然而,原代码在这里存在逻辑错误。内层
while
循环将剩余的count
个位置填充为'\0'
后,返回的是des
指针,而des
此时已经指向填充完'\0'
后的位置,并非目标字符串的起始位置,这会导致调用者无法正确获取复制后的字符串。
*des = '\0';return bak;
}
- 若
count
为 0,说明已经复制了count
个字符,此时在目标字符串末尾添加'\0'
作为字符串结束符,然后返回bak
指针,即目标字符串的起始位置。
4. strcat
- 连接字符串
char *strcat(char *dest, const char *src);
- 功能:把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除*dest原来末尾的“\0”)。要保证*dest足够长,以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针。
- 示例:
#include <stdio.h>
#include <string.h>int main() {char dest[20] = "Hello";char src[] = ", World!";strcat(dest, src);printf("连接后的字符串: %s\n", dest);return 0;
}
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* myStrcat(char *des,char *src)
{assert(des!=NULL&&src!=NULL);//linux下的ANSI c的函数库char *bak=des;while(*des!='\0'){des++; }while((*des++=*src++)!='\0'){*des='\0';return bak;}
}char* myStrcat2(char *des,char *src)
{char *bak=des;strcpy(des+strlen(des),src);//GNU C return bak;}
}char* myStrcat3(char *des,char *src)
{assert(des!=NULL&&src!=NULL);//OpenBSD char *bak=des;for(;*des!='\0';des++);while((*des++=*src++)!='\0'){*des='\0';return bak;}
}int main()
{char str[128]="staacthhhhh";char *p="handsome";myStrcat3(str,p);puts(str);return 0;
}
代码分析
myStrcat
函数
char* myStrcat(char *des, char *src)
{assert(des!=NULL && src!=NULL); // linux下的ANSI c的函数库char *bak = des;while (*des != '\0') {des++;}while ((*des++ = *src++) != '\0') {*des = '\0';return bak;}
}
- 功能:尝试将源字符串
src
拼接到目标字符串des
的末尾。 - 参数:
des
是目标字符串的指针,src
是源字符串的指针。 - 代码流程:
assert(des!=NULL && src!=NULL);
:使用断言检查des
和src
指针是否为NULL
,若为NULL
则程序终止。char *bak = des;
:保存目标字符串的起始地址,方便最后返回。while (*des != '\0') { des++; }
:将指针des
移动到目标字符串的末尾。while ((*des++ = *src++) != '\0')
:把源字符串的字符逐个复制到目标字符串末尾。- 问题所在:
*des = '\0';
和return bak;
语句在循环内部,这会导致只复制源字符串的第一个字符就返回,并且会将该字符后面的位置置为'\0'
,无法完成整个字符串的拼接。
myStrcat2
函数
char* myStrcat2(char *des, char *src)
{char *bak = des;strcpy(des + strlen(des), src); // GNU C return bak;
}
- 功能:借助标准库函数
strcpy
实现字符串拼接。 - 参数:
des
是目标字符串的指针,src
是源字符串的指针。 - 代码流程:
char *bak = des;
:保存目标字符串的起始地址。strcpy(des + strlen(des), src);
:先使用strlen(des)
找到目标字符串的末尾位置,再调用strcpy
函数将源字符串复制到该位置。return bak;
:返回目标字符串的起始地址。。
myStrcat3
函数
char* myStrcat3(char *des, char *src)
{assert(des != NULL && src != NULL);char *bak = des;// 找到目标字符串的末尾for (; *des != '\0'; des++);// 连接源字符串while ((*des++ = *src++) != '\0');return bak;
}
- 功能:将源字符串
src
拼接到目标字符串des
的末尾。 - 参数:
des
是目标字符串的指针,src
是源字符串的指针。 - 代码流程:
assert(des != NULL && src != NULL);
:使用断言检查指针是否为NULL
。char *bak = des;
:保存目标字符串的起始地址。for (; *des != '\0'; des++);
:将指针des
移动到目标字符串的末尾。while ((*des++ = *src++) != '\0');
:逐个字符复制源字符串到目标字符串末尾,直到源字符串结束。return bak;
:返回目标字符串的起始地址。
myStrcpy
函数,myStrcpy2
函数,myStrcpy3
函数 实现功能一样
5. strncat
- 连接指定长度的字符串
char *strncat(char *dest, const char *src, size_t n);
- 功能:将字符串
src
的前n
个字符连接到dest
的末尾,并自动添加'\0'
。 - 示例:
#include <stdio.h>
#include <string.h>int main() {char dest[20] = "Hello";char src[] = ", World!";strncat(dest, src, 6);printf("连接后的字符串: %s\n", dest);return 0;
}
6. strcmp
- 比较字符串
int strcmp(const char *str1, const char *str2);
- 功能:比较两个字符串
str1
和str2
。如果str1
小于str2
,返回一个负数;如果str1
等于str2
,返回 0;如果str1
大于str2
,返回一个正数。 - 示例:
#include <stdio.h>
#include <string.h>int main() {char str1[] = "apple";char str2[] = "banana";int result = strcmp(str1, str2);if (result < 0) {printf("%s 小于 %s\n", str1, str2);} else if (result == 0) {printf("%s 等于 %s\n", str1, str2);} else {printf("%s 大于 %s\n", str1, str2);}return 0;
}
7. strncmp
- 比较指定长度的字符串
int strncmp(const char *str1, const char *str2, size_t n);
- 功能:比较两个字符串
str1
和str2
的前n
个字符。返回值规则与strcmp
相同。 - 示例:
#include <stdio.h>
#include <string.h>int main() {char str1[] = "apple";char str2[] = "appetizer";int result = strncmp(str1, str2, 3);if (result < 0) {printf("前 3 个字符中,%s 小于 %s\n", str1, str2);} else if (result == 0) {printf("前 3 个字符中,%s 等于 %s\n", str1, str2);} else {printf("前 3 个字符中,%s 大于 %s\n", str1, str2);}return 0;
自定义字符串比较函数 myStrcmp
// 自定义字符串比较函数
int myStrcmp(char *str1, char *str2) {
- 此函数的功能是比较两个字符串
str1
和str2
的大小,返回一个整数值来表示比较结果。 - 参数
str1
和str2
是指向字符的指针,分别指向要进行比较的两个字符串。
// 备份原始指针char *bakStr1 = str1;char *bakStr2 = str2;
- 把
str1
和str2
的原始指针备份到bakStr1
和bakStr2
中。在后续操作里,str1
和str2
指针会移动,备份原始指针是为了在需要时能够回到字符串的起始位置。不过在这段代码中,备份的指针并没有被实际使用。
// 逐个字符比较while (*str1 && *str2 && (*str1 == *str2)) {str1++;str2++;}
- 这是一个
while
循环,用于逐个字符地比较str1
和str2
。*str1
和*str2
分别表示str1
和str2
指针所指向的字符。*str1 && *str2
确保两个字符串都还未结束(即未遇到字符串结束符'\0'
)。(*str1 == *str2)
检查当前字符是否相等。- 若以上条件都满足,就将
str1
和str2
指针向后移动一位,继续比较下一个字符。
// 根据比较结果返回相应的值if (*str1 < *str2) {return -1;} else if (*str1 > *str2) {return 1;} else {return 0;}
- 当
while
循环结束后,就根据当前str1
和str2
指针所指向的字符的大小关系来返回相应的值:- 若
*str1 < *str2
,表明str1
小于str2
,返回 -1。 - 若
*str1 > *str2
,表明str1
大于str2
,返回 1。 - 若
*str1
等于*str2
,意味着两个字符串相等或者同时结束,返回 0。
- 若
主函数 main
int main() {char *p1 = "chenlichenaa";char *p2 = "chenlichenab";
- 定义两个字符指针
p1
和p2
,分别指向两个字符串常量"chenlichenaa"
和"chenlichenab"
。
int ret = myStrcmp(p1, p2); // 1 0 -1
- 调用
myStrcmp
函数,将p1
和p2
作为参数传入,比较这两个字符串。 - 把比较结果存储在
ret
变量中。
if (ret == 0) {puts("两个字符串一样");} else if (ret < 0) {puts("第一个字符串小于第二个字符串");} else {puts("第一个字符串大于第二个字符串");}
- 根据
ret
的值输出相应的比较结果信息:- 若
ret
等于 0,使用puts
函数输出"两个字符串一样"
。 - 若
ret
小于 0,输出"第一个字符串小于第二个字符串"
。 - 若
ret
大于 0,输出"第一个字符串大于第二个字符串"
。
- 若
printf("RET=%d\n", ret);return 0;
}
- 使用
printf
函数输出比较结果的具体数值。 return 0;
表示程序正常结束,返回值 0 通常表示程序执行成功。
8.strchr
查找子字符
是C 语言标准库 <string.h>
里的一个函数,其主要功能是在指定字符串里查找某个特定字符首次出现的位置。下面从多个方面详细介绍 strchr
函数:
函数原型
char *strchr(const char *str, int c);
参数说明
str
:这是一个指向要被搜索的字符串的指针,类型为const char *
,意味着在函数内部不会对该字符串进行修改。c
:需要查找的字符,虽然参数类型是int
,但实际上存储的是字符的 ASCII 码值。
返回值
- 若在字符串
str
中找到了字符c
,函数会返回一个指向该字符首次出现位置的指针。 - 若在字符串
str
中未找到字符c
,函数会返回NULL
。
工作原理
strchr
函数会从字符串 str
的起始位置开始,逐个字符进行比较,直至找到字符 c
或者到达字符串的结束符 '\0'
。一旦找到字符 c
,就会返回指向该字符的指针;若遍历完整个字符串都未找到,就返回 NULL
。
示例代码
#include <stdio.h>
#include <string.h>int main() {const char *str = "Hello, World!";char target = 'o';char *result = strchr(str, target);if (result != NULL) {printf("字符 '%c' 首次出现在字符串中的位置是: %ld\n", target, result - str);} else {printf("未在字符串中找到字符 '%c'\n", target);}return 0;
}
代码解释
- 定义字符串和目标字符:
const char *str = "Hello, World!";
char target = 'o';
这里定义了一个字符串 str
和要查找的目标字符 target
。
- 调用
strchr
函数:
char *result = strchr(str, target);
调用 strchr
函数在字符串 str
中查找字符 target
,并将返回的指针存储在 result
中。
- 处理返回结果:
if (result != NULL) {printf("字符 '%c' 首次出现在字符串中的位置是: %ld\n", target, result - str);
} else {printf("未在字符串中找到字符 '%c'\n", target);
}
- 若
result
不为NULL
,说明找到了目标字符,通过result - str
计算出目标字符在字符串中的位置(偏移量),并输出结果。 - 若
result
为NULL
,说明未找到目标字符,输出相应的提示信息。
9. strstr
- 查找子字符串
-
strstr
函数原型char *strstr(const char *str1, const char *str2);
参数说明
str1
:要进行搜索的主字符串,类型为const char *
,表示在函数内部不会修改该字符串。str2
:要查找的子字符串,同样类型为const char *
。- 若
str2
是str1
的子串,函数返回str2
在str1
中首次出现的地址。 - 若
str2
不是str1
的子串,函数返回NULL
。
返回值
- 若
str2
是str1
的子串,函数返回str2
在str1
中首次出现的地址。 - 若
str2
不是str1
的子串,函数返回NULL
。
标准库使用示例
#include <stdio.h>
#include <string.h>int main() {const char *str1 = "Hello, World!";const char *str2 = "World";char *result = strstr(str1, str2);if (result != NULL) {printf("子串 '%s' 在主串中首次出现的位置是: %ld\n", str2, result - str1);} else {printf("未在主串中找到子串 '%s'\n", str2);}return 0;
}
运行结果
D:\c语言\第七章字符串>a.exe
子串 'World' 在主串中首次出现的位置是: 7
char *strstr(const char *str1, const char *str2);
#include <stdio.h>
#include <string.h>int main() {char haystack[] = "Hello, World!";char needle[] = "World";char *result = strstr(haystack, needle);if (result != NULL) {printf("找到子字符串,位置: %ld\n", result - haystack);} else {printf("未找到子字符串\n");}return 0;
}
10.assert-断言
assert
是一个宏,定义在 <assert.h>
头文件中。它的主要作用是在程序运行时对某个条件进行检查,若条件为假(即条件表达式的值为 0),程序就会终止运行,并输出一条错误信息,其中包含断言失败的文件名、行号以及具体的断言表达式。
语法格式
#include <assert.h>
assert(expression);
expression
:这是一个需要被检查的条件表达式,它可以是任何合法的 C 语言表达式,例如变量比较、函数返回值判断等。
工作原理
-
当程序执行到
assert
语句时,会先计算expression
的值: - 若
expression
的值为真(非 0),assert
语句不会产生任何影响,程序会继续正常执行后续代码。 - 若
expression
的值为假(0),assert
会输出错误信息,并且调用abort()
函数终止程序的运行。
示例代码
#include <stdio.h>
#include <assert.h>// 一个简单的除法函数
int divide(int a, int b) {// 使用 assert 检查除数是否为 0assert(b != 0);return a / b;
}int main() {int result;// 正常情况,除数不为 0result = divide(10, 2);printf("10 / 2 = %d\n", result);// 异常情况,除数为 0result = divide(10, 0);printf("这行代码不会被执行\n");return 0;
}
代码解释
- 在
divide
函数中,使用assert(b != 0);
来检查除数b
是否为 0。 - 当调用
divide(10, 2)
时,b
的值为 2,条件b != 0
为真,assert
不会产生任何影响,程序会继续执行并输出结果。 - 当调用
divide(10, 0)
时,b
的值为 0,条件b != 0
为假,assert
会输出错误信息,并且终止程序的运行,所以printf("这行代码不会被执行\n");
不会被执行。
11.strtok
-字符串分割
是 C 语言标准库 <string.h>
中一个非常实用的函数,用于将字符串按照指定的分隔符进行分割。下面将从函数原型、功能、使用示例、注意事项等方面详细介绍 strtok
函数。
函数原型
char *strtok(char *str, const char *delim);
参数解释
str
:指向要被分割的字符串的指针。在第一次调用strtok
时,需要传入要分割的字符串;后续调用时,应传入NULL
,表示继续对之前的字符串进行分割操作。需要注意的是,strtok
函数会修改原字符串,它会将找到的分隔符替换为字符串结束符'\0'
。delim
:指向包含分隔符字符的字符串的指针。strtok
函数会根据这个字符串中的字符来确定分割位置。例如,如果delim
为",;:"
,那么逗号、分号和冒号都会被当作分隔符。
返回值
- 如果找到了下一个标记(子字符串),则返回指向该标记的指针。
- 如果没有更多的标记可找,返回
NULL
。
功能描述
strtok
函数会在字符串 str
中搜索由 delim
中指定的分隔符分隔的标记(子字符串)。第一次调用时,它会从 str
的起始位置开始查找,将找到的第一个分隔符替换为 '\0'
,并返回指向该标记的指针。后续调用时,传入 NULL
作为第一个参数,strtok
会继续从上次停止的位置开始查找下一个标记,直到字符串结束。
使用示例
#include <stdio.h>
#include <string.h>int main() {char str[] = "apple,banana;cherry:date";const char delim[] = ",;: ";// 第一次调用 strtok,传入要分割的字符串char *token = strtok(str, delim);// 循环获取分割后的每个子字符串while (token != NULL) {printf("%s\n", token);// 后续调用 strtok 传入 NULLtoken = strtok(NULL, delim);}return 0;
}
运行结果
D:\c语言\第七章字符串>a.exe
apple
banana
cherry
date
代码解释
- 定义字符串和分隔符:定义了一个待分割的字符串
str
和包含分隔符的字符串delim
。 - 第一次调用
strtok
:将str
和delim
作为参数传入strtok
函数,它会返回第一个分割后的子字符串(即"apple"
)的指针,并将原字符串中的逗号替换为'\0'
。 - 循环获取后续子字符串:在
while
循环中,不断调用strtok
函数,传入NULL
作为第一个参数,直到strtok
返回NULL
,表示字符串分割完毕。 - 输出结果:每次获取到子字符串后,使用
printf
函数将其输出。
相关文章:
C语言:几种字符串常用的API
字符串的常用操作 C 语言的标准库 <string.h> 提供了很多用于处理字符串的函数。 1. strlen - 计算字符串长度 size_t strlen(const char *str);功能:计算字符串 str 的长度,不包含字符串结束符 \0。 2.strcpy - 复制字符串 char *strcpy(char…...
Django构建安全中间件实用示例
Django安全中间件实用指南 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django安全中间件实用指南什么是Django中的中间件?Django中的安全中间件特性配置示例配置示例配置示例示…...
排序算法(快速排序,选择排序......)【泪光2929】
hello,大家好!今天给大家分享一下各种排序: 1,选择排序 首先从原始数组中 选择最小的1个数据,将其和位于第1个位置的数据交换。接着从剩下的n-1个数据中选择次小的1个元素,将其和第2个位置的数据交换然后…...
UE5学习记录part14
第17节 enemy behavior 173 making enemies move: AI Pawn Navigation 按P查看体积 So its very important that our nav mesh bounds volume encompasses all of the area that wed like our 因此,我们的导航网格边界体积必须包含我们希望 AI to navigate in and …...
树莓派llama.cpp部署DeepSeek-R1-Distill-Qwen-1.5B
树莓派的性能太低了,我们需要对模型进行量化才能使用,所以现在的方案是,在windows上将模型格式和量化处理好,然后再将模型文件传输到树莓派上。而完成上面的操作就需要部署llama.cpp。 三、环境的准备 这里要求大家准备…...
Llama 4 最新发布模型分析
1. 引言 在2025年4月5日,Meta公司正式发布了最新一代大型语言模型Llama 4系列,包括Llama 4 Scout和Llama 4 Maverick。该模型添加了多模态支持,能够处理文本、图像、音频和视频数据,实现更加充分的AI功能应用。 2. 技术特性 2.1…...
Llama 4 家族:原生多模态 AI 创新的新时代开启
0 要点总结 Meta发布 Llama 4 系列的首批模型,帮用户打造更个性化多模态体验Llama 4 Scout 是有 170 亿激活参数、16 个专家模块的模型,同类中全球最强多模态模型,性能超越以往所有 Llama 系列模型,能在一张 NVIDIA H100 GPU 上运…...
如何让eDrawings html文件在Chrome浏览器上展示——allWebPlugin中间件扩展
应用背景 eDrawing html文件是仅可在 Internet Explorer 5.5 和以上版本中查阅,由于IE浏览器限制,目前使用非常不方便,为了不修改html的请提下,在chrome浏览器查阅原本html文件,可使用安装allWebPlugin中间件扩展。 a…...
【内网安全】DHCP 饿死攻击和防护
正常情况:PC2可以正常获取到DHCP SERVER分别的IP地址查看DHCP SERCER 的ip pool地址池可以看到分配了一个地址、Total 253个 Used 1个 使用kali工具进行模拟攻击 进行DHCP DISCOVER攻击 此时查看DHCP SERVER d大量的抓包:大量的DHCP Discover包 此时模…...
keepalived高可用介绍
keepalived 是 Linux 一个轻量级的高可用解决方案,提供了心跳检测和资源接管、检测集群中的系统服务,在集群节点间转移共享IP 地址的所有者等。 工作原理 keepalived 通过 VRRP(virtual router redundancy protocol)虚拟路由冗余…...
基于大模型的脑梗死全流程诊疗技术方案
目录 《基于大模型的脑梗死全流程诊疗技术方案》一、核心算法实现1. 多模态特征融合算法(术前规划)2. 术中实时预警算法二、系统模块设计1. 术前规划系统流程图2. 术中实时监控系统架构三、技术验证方案1. 模型验证矩阵2. 实验验证设计四、关键技术创新点五、工程实现规范1. …...
ngx_timezone_update
定义在 src\os\unix\ngx_time.c void ngx_timezone_update(void) { #if (NGX_FREEBSD)if (getenv("TZ")) {return;}putenv("TZUTC");tzset();unsetenv("TZ");tzset();#elif (NGX_LINUX)time_t s;struct tm *t;char buf[4];s tim…...
Redis 热key问题怎么解决?
Redis 热 Key 问题分析与解决方案 热 Key(Hot Key)是指被高频访问的某个或多个 Key,导致单个 Redis 节点负载过高,可能引发性能瓶颈甚至服务崩溃。以下是常见原因及解决方案: 1. 热 Key 的常见原因 突发流量:如明星八卦、秒杀商品、热门直播等场景。缓存设计不合理:如全…...
JavaWeb(楠)
JavaWeb21-1:Java Web开发的地位、Tomcat服务器 Java Web开发概述 主流地位:Java可用于移动端、桌面应用、机器学习等多个领域,但在Web开发领域优势显著,是Java最主流的研发方向。市场上95%以上的Web端开发都使用Java,…...
批量将 JSON 转换为 Excel/思维导入等其它格式
json 格式相信对大家来说都不陌生,这是一种轻量级的结构化数据,可以对对象进行描述。json 格式也是一种普通的文本文件格式,用记事本就能够打开编辑 json 格式的文件,可以很方便的转换为其他格式。今天要给大家介绍的就是如何将 j…...
C# Winform 入门(13)之通过WebServer查询天气预报
展示 控件 添加WebServer 右键项目> 添加引用> 添加服务引用 天气预报URL: WeatherWebService Web 服务WeatherWebService Web 服务http://www.webxml.com.cn/WebServices/WeatherWebService.asmx 查询按钮实现 private void btn_Inquiry_Click(object sender, EventA…...
算法思想之滑动窗口(一)
欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之滑动窗口(一) 发布时间:2025.4.6 隶属专栏:算法 目录 滑动窗口算法介绍核心思想时间复杂度适用场景注意事项 例题长度最小的子数组题目链接题目描述算法思路代码实现 无重复字符的…...
爬虫工程师无意义的活
30岁的年龄;这个年龄大家都是成年人;都是做父母的年龄了;你再工位上的心态会发生很大变化的; 爬虫工程师基本都是如此;社会最low的一帮连销售都做不了的;单子都开不出来的然后转行做爬虫工程师的;这样的人基本不太和社会接触; 你作为爬虫初级工程师就敲着键盘然后解析着html;…...
DeepSeek 关联公司公布新型数据采集专利 提升数据采集效率与质量
4 月 1 日,国家知识产权局公布了一项由 DeepSeek 关联公司杭州深度求索人工智能基础技术研究有限公司申请的专利,名为 “一种广度数据采集的方法及其系统”,公开号为 CN 119739917 A,申请日期可追溯至 2024 年 12 月。此专利的发布…...
实际犯错以及复盘1
Ds1302 需要两个 一个Set_Rtc 一个Read_Rtc : 本质 read是 85-2i 的 写入是84-2i 然后 写入的时候 是需要对 0x8e 进行 0x00 和0x80进行解开和 锁定的开头结尾。 使用的时候 赋值给ucRtc[i] 然后 主函数使用的时候 需要直接写个(ucRtc) 因为unsigned char* 默认的…...
初探:简道云系统架构及原理
一、系统架构概述 简道云作为一款低代码开发平台,其架构设计以模块化和云端协同为核心,主要分为以下层次: 1. 前端层 可视化界面:基于Web的拖拽式表单设计器,支持动态渲染(React/Vue框架)。多…...
Nginx负载均衡时如何为指定ip配置固定服务器
大家在用Nginx做负载均衡时,一般是采用默认的weight权重指定或默认的平均分配实现后端服务器的路由,还有一种做法是通过ip_hash来自动计算进行后端服务器的路由,但最近遇到一个问题,就是希望大部分用户采用ip_hash自动分配后端服务…...
玩转MCP:用百度热搜采集案例快速上手并接入cline
MCP的大火,让MCP服务器开发也变得热门,上一篇文章: 手搓MCP客户端&服务端:从零到实战极速了解MCP是什么? 手搓了一个极其简单的小场景的MCP实战案例,详细的安装环境及操作步骤已经讲过了,本文不在重复…...
003集——《利用 C# 与 AutoCAD API 开发 WPF 随机圆生成插件》(侧栏菜单+WPF窗体和控件+MVVM)
本案例聚焦于开发一款特色鲜明的 AutoCAD 插件。其核心功能在于,用户在精心设计的 WPF 控件界面中输入期望生成圆的数量,完成输入后,当用户点击 “生成” 按钮,一系列联动操作随即展开。通过数据绑定与命令绑定这一精妙机制&#…...
设计模式简述(十)责任链模式
责任链模式 描述基本使用使用 描述 如果一个请求要经过多个类似或相关处理器的处理。 可以考虑将这些处理器添加到一个链上,让请求逐个经过这些处理器进行处理。 通常,在一个业务场景下会对整个责任链进行初始化,确定这个链上有哪些Handler…...
分组(二分查找)
#include <bits/stdc.h> using namespace std; const int N1e55; int a[N]; int n,k;bool f(int x){int num1;int ma[1];for(int i2;i<n;i){if(a[i]-m>x){ // 当前元素加入当前组会超过极差 xnum; // 新开一组ma[i]; // 新组的最小值设为当前元素}}r…...
vue的主要核心文件介绍
1.package.json 查看依赖包的版本 项目基本信息记录 项目标识:记录项目名称(name 字段)、版本号(version 字段)、描述(description 字段)等基础信息,方便识别和管理项目。例如&…...
从奖励到最优决策:动作价值函数与价值学习
从奖励到最优决策:动作价值函数与价值学习 价值学习动作价值函数对 U t U_t Ut求期望得到动作价值函数动作价值函数的意义最优动作价值函数(Optimal Action-Value Function)如何理解 Q ∗ Q^* Q∗函数 价值学习的基本思想Deep Q-Network(DQN)DQN玩游戏的具体流程如…...
DApp实战篇:先用前端起个项目
前言 本篇将使用vue框架quasar起一个项目,为了防止大家不会使用quasar,本篇详细讲解一下quasar如何使用。 quasar 如果你不想深入了解quasar,其实你完全可以将quasar当成一个vue的组件库即可,它是一个类谷歌Material风格的UI组件库,但同时它又是一个基于vue的强大框架。…...
论文阅读11——V2V-LLM:采用多模式大型语言模型的车对车协同自动驾驶
原文地址: 2502.09980https://arxiv.org/pdf/2502.09980 论文翻译: V2V-LLM: Vehicle-to-Vehicle Cooperative Autonomous Driving with Multi-Modal Large Language Models V2V-LLM:采用多模式大型语言模型的车对车协同自动驾驶 摘要&#…...
NLP 梳理01 — 文本预处理和分词
文章目录 一、说明二、文本预处理概述2.1 为什么要预处理文本?2.2 文本预处理的常见步骤2.3 什么是令牌化?2.4 为什么令牌化很重要? 三、分词类型四、用于分词化的工具和库五、实际实施六、编写函数以对文本进行标记七、结论 一、说明 本文总…...
Windows11 优雅的停止更新、禁止更新
网上有很多关闭自动更新的方法,改注册表、修改组策略编辑器、禁用Windows Update等等,大同小异,但最后奏效的寥寥无几,今天给大家带来另一种关闭win11自动更新的方法,亲测有效! 1、winR 打开运行窗口&…...
Kafka 中的 offset 提交问题
手动提交和自动提交 我们来一次性理清楚:Kafka 中的自动提交 vs 手动提交,到底区别在哪,怎么用,什么场景适合用哪个👇 🧠 一句话总结 ✅ 自动提交:Kafka 每隔一段时间自动提交 offset ✅ 手动…...
PowerBI窗口函数与视觉计算
文章目录 一、 窗口函数1.1 OFFSET(动态查询、求连续值)1.1.1 不使用orderBy1.1.2 使用orderBy1.1.3 统计连续值的最大出现次数(待补) 1.2 INDEX(静态查询)1.3 WINDOW(滚动求和、累计求和、帕累…...
代码随想录算法训练营Day22
回溯知识 力扣77.组合【medium】 一、回溯知识 1、定义 回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。 2、回溯法的效率 回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案…...
几种常见的HTTP方法之GET和POST
如大家所了解的,每条 HTTP 请求报文都必须包含一个请求方法,这个方法会告诉服务器要执行什么操作(例如获取一个 Web 页面、运行一个网关程序、删除一个文件等)。常见的几种 HTTP 方法如下: GET: 请求指定的…...
Nginx之https重定向为http
为了将Nginx中443端口的请求重定向到80端口,你可以按照以下步骤进行操作: 确认Nginx已经正确安装并运行: 确保Nginx服务已经在你的系统上安装并运行。你可以通过运行以下命令来检查Nginx的状态(具体命令可能因操作系统而异&a…...
落地DevOps文化:运维变革的正确打开方式
落地DevOps文化:运维变革的正确打开方式 DevOps,这个近年来被谈论得沸沸扬扬的概念,是企业数字化转型的一把钥匙。然而,很多公司虽然喊着“要上DevOps”,却苦于如何真正落地。而DevOps不仅仅是技术工具的堆砌,更是一种文化的重塑。从我的经历来看,DevOps实施的核心在于…...
《C++后端开发最全面试题-从入门到Offer》目录
当今科技行业对C++开发者的需求持续高涨,从金融科技到游戏开发,从嵌入式系统到高性能计算,C++凭借其卓越的性能和灵活性始终占据着关键地位。然而,成为一名优秀的C++工程师并非易事,不仅需要扎实的语言基础,还要掌握现代C++特性、设计模式、性能优化技巧以及各种工业级开…...
24统计建模国奖论文写作框架2(机器学习+自然语言处理类)(附原文《高校负面舆情成因与演化路径研究》)
一、引言 研究背景及意义 文献综述 研究内容与创新点 二、高校负面舆情热点现状分析 案例数据的获取与处理 高效负面舆情热点词频分析 高效负面舆情热点变化趋势分析 三、高校负面舆情成因分析 高校负面舆情变量的选取与赋值 基于QCA方法的高校负面舆情成因分析 四、…...
论文阅读笔记——Deformable Radial Kernel Splatting
DRK 论文 DRK(可变形径向核)的核心创新正是通过极坐标参数化与切平面投影,对传统3D高斯泼溅(3D-GS)进行了多维度的优化。 传统 3DGS 依赖径向对称的高斯核,只能表示平滑、各向同性的形状(球体、…...
网络编程—TCP/IP模型(IP协议)
上篇文章: 网络编程—TCP/IP模型(TCP协议)https://blog.csdn.net/sniper_fandc/article/details/147011479?fromshareblogdetail&sharetypeblogdetail&sharerId147011479&sharereferPC&sharesourcesniper_fandc&sharef…...
Android NDK C/C++交叉编译脚本
以下是 Android (arm64-v8a) 交叉编译 C/C 项目的完整脚本模板,基于 NDK 工具链,支持自定义源文件编译为静态库/动态库/可执行文件: 1. 基础交叉编译脚本 (build_android.sh) bash 复制 #!/bin/bash# Android 交叉编译脚本 (arm64-…...
IS-IS-单区域的配置
一、IS-IS的概念 IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是一种链路状态路由协议,最初设计用于OSI(Open Systems Interconnection)参考模型的网络层(CL…...
Java EE期末总结(第四章)
目录 一、ORM框架 二、MyBatis与Hibernate 1、 概念与设计理念 2、SQL 控制 3、学习成本 4、开发效率 三、MyBatisAPI 1、SqlSessionFactoryBuilder 2、SqlSessionFactory 3、SqlSession 四、MyBatis配置 1、核心依赖与日志依赖 2、建立.XML映射文件 3、建立映射…...
Kafka 的选举机制
Kafka 的选举机制在 Zookeeper 模式 和 KRaft 模式 下有所不同,主要体现在 领导选举 和 集群元数据管理 的方式上。下面详细介绍这两种模式下 Kafka 如何进行选举机制。 1. Zookeeper 模式下的选举机制 在早期的 Kafka 架构中,集群的元数据管理和选举机…...
FreeRTOS移植笔记:让操作系统在你的硬件上跑起来
一、为什么需要移植? FreeRTOS就像一套"操作系统积木",但不同硬件平台(如STM32、ESP32、AVR等)的CPU架构和外设差异大,需要针对目标硬件做适配配置。移植工作就是让FreeRTOS能正确管理你的硬件资源。 二、…...
设计模式简述(十二)策略模式
策略模式 描述基本使用使用传统策略模式的缺陷以及规避方法 枚举策略描述基本使用使用 描述 定义一组策略,并将其封装起来到一个策略上下文中。 由调用者决定应该使用哪种策略,并且可以动态替换 基本使用 定义策略接口 public interface IStrategy {…...
如何在idea中快速搭建一个Spring Boot项目?
文章目录 前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热启动(热部署)结语 前言 Spring Boot 凭借其便捷的开发特性,极大提升了开发效率,为 Java 开发工作带来诸多便利。许多大伙伴希望快速…...
【注解简化配置的原理是什么】
注解(Annotation)简化配置的核心原理是将原本分散在外部文件(如XML、properties)中的元数据直接内嵌到代码中,通过声明式编程让框架或工具自动处理这些元数据,从而减少手动配置的复杂度。以下是其实现原理的…...