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

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 是源字符串的指针。
  • 代码流程
    1. assert(des!=NULL && src!=NULL);:使用断言检查 des 和 src 指针是否为 NULL,若为 NULL 则程序终止。
    2. char *bak = des;:保存目标字符串的起始地址,方便最后返回。
    3. while (*des != '\0') { des++; }:将指针 des 移动到目标字符串的末尾。
    4. while ((*des++ = *src++) != '\0'):把源字符串的字符逐个复制到目标字符串末尾。
    5. 问题所在*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 是源字符串的指针。
  • 代码流程
    1. char *bak = des;:保存目标字符串的起始地址。
    2. strcpy(des + strlen(des), src);:先使用 strlen(des) 找到目标字符串的末尾位置,再调用 strcpy 函数将源字符串复制到该位置。
    3. 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 是源字符串的指针。
  • 代码流程
    1. assert(des != NULL && src != NULL);:使用断言检查指针是否为 NULL
    2. char *bak = des;:保存目标字符串的起始地址。
    3. for (; *des != '\0'; des++);:将指针 des 移动到目标字符串的末尾。
    4. while ((*des++ = *src++) != '\0');:逐个字符复制源字符串到目标字符串末尾,直到源字符串结束。
    5. 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;
}

代码解释

  1. 定义字符串和目标字符
const char *str = "Hello, World!";
char target = 'o';

这里定义了一个字符串 str 和要查找的目标字符 target

  1. 调用 strchr 函数
char *result = strchr(str, target);

调用 strchr 函数在字符串 str 中查找字符 target,并将返回的指针存储在 result 中。

  1. 处理返回结果
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

代码解释

  1. 定义字符串和分隔符:定义了一个待分割的字符串 str 和包含分隔符的字符串 delim
  2. 第一次调用 strtok:将 str 和 delim 作为参数传入 strtok 函数,它会返回第一个分割后的子字符串(即 "apple")的指针,并将原字符串中的逗号替换为 '\0'
  3. 循环获取后续子字符串:在 while 循环中,不断调用 strtok 函数,传入 NULL 作为第一个参数,直到 strtok 返回 NULL,表示字符串分割完毕。
  4. 输出结果:每次获取到子字符串后,使用 printf 函数将其输出。

相关文章:

C语言:几种字符串常用的API

字符串的常用操作 C 语言的标准库 <string.h> 提供了很多用于处理字符串的函数。 1. strlen - 计算字符串长度 size_t strlen(const char *str);功能&#xff1a;计算字符串 str 的长度&#xff0c;不包含字符串结束符 \0。 2.strcpy - 复制字符串 char *strcpy(char…...

Django构建安全中间件实用示例

Django安全中间件实用指南 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django安全中间件实用指南什么是Django中的中间件?Django中的安全中间件特性配置示例配置示例配置示例示…...

排序算法(快速排序,选择排序......)【泪光2929】

hello&#xff0c;大家好&#xff01;今天给大家分享一下各种排序&#xff1a; 1&#xff0c;选择排序 首先从原始数组中 选择最小的1个数据&#xff0c;将其和位于第1个位置的数据交换。接着从剩下的n-1个数据中选择次小的1个元素&#xff0c;将其和第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 因此&#xff0c;我们的导航网格边界体积必须包含我们希望 AI to navigate in and …...

树莓派llama.cpp部署DeepSeek-R1-Distill-Qwen-1.5B

树莓派的性能太低了&#xff0c;我们需要对模型进行量化才能使用&#xff0c;所以现在的方案是&#xff0c;在windows上将模型格式和量化处理好&#xff0c;然后再将模型文件传输到树莓派上。而完成上面的操作就需要部署llama.cpp。 三、环境的准备 这里要求大家准备…...

Llama 4 最新发布模型分析

1. 引言 在2025年4月5日&#xff0c;Meta公司正式发布了最新一代大型语言模型Llama 4系列&#xff0c;包括Llama 4 Scout和Llama 4 Maverick。该模型添加了多模态支持&#xff0c;能够处理文本、图像、音频和视频数据&#xff0c;实现更加充分的AI功能应用。 2. 技术特性 2.1…...

Llama 4 家族:原生多模态 AI 创新的新时代开启

0 要点总结 Meta发布 Llama 4 系列的首批模型&#xff0c;帮用户打造更个性化多模态体验Llama 4 Scout 是有 170 亿激活参数、16 个专家模块的模型&#xff0c;同类中全球最强多模态模型&#xff0c;性能超越以往所有 Llama 系列模型&#xff0c;能在一张 NVIDIA H100 GPU 上运…...

如何让eDrawings html文件在Chrome浏览器上展示——allWebPlugin中间件扩展

应用背景 eDrawing html文件是仅可在 Internet Explorer 5.5 和以上版本中查阅&#xff0c;由于IE浏览器限制&#xff0c;目前使用非常不方便&#xff0c;为了不修改html的请提下&#xff0c;在chrome浏览器查阅原本html文件&#xff0c;可使用安装allWebPlugin中间件扩展。 a…...

【内网安全】DHCP 饿死攻击和防护

正常情况&#xff1a;PC2可以正常获取到DHCP SERVER分别的IP地址查看DHCP SERCER 的ip pool地址池可以看到分配了一个地址、Total 253个 Used 1个 使用kali工具进行模拟攻击 进行DHCP DISCOVER攻击 此时查看DHCP SERVER d大量的抓包&#xff1a;大量的DHCP Discover包 此时模…...

keepalived高可用介绍

keepalived 是 Linux 一个轻量级的高可用解决方案&#xff0c;提供了心跳检测和资源接管、检测集群中的系统服务&#xff0c;在集群节点间转移共享IP 地址的所有者等。 工作原理 keepalived 通过 VRRP&#xff08;virtual router redundancy protocol&#xff09;虚拟路由冗余…...

基于大模型的脑梗死全流程诊疗技术方案

目录 《基于大模型的脑梗死全流程诊疗技术方案》一、核心算法实现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&#xff1a;Java Web开发的地位、Tomcat服务器 Java Web开发概述 主流地位&#xff1a;Java可用于移动端、桌面应用、机器学习等多个领域&#xff0c;但在Web开发领域优势显著&#xff0c;是Java最主流的研发方向。市场上95%以上的Web端开发都使用Java&#xff0c…...

批量将 JSON 转换为 Excel/思维导入等其它格式

json 格式相信对大家来说都不陌生&#xff0c;这是一种轻量级的结构化数据&#xff0c;可以对对象进行描述。json 格式也是一种普通的文本文件格式&#xff0c;用记事本就能够打开编辑 json 格式的文件&#xff0c;可以很方便的转换为其他格式。今天要给大家介绍的就是如何将 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…...

算法思想之滑动窗口(一)

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;算法思想之滑动窗口(一) 发布时间&#xff1a;2025.4.6 隶属专栏&#xff1a;算法 目录 滑动窗口算法介绍核心思想时间复杂度适用场景注意事项 例题长度最小的子数组题目链接题目描述算法思路代码实现 无重复字符的…...

爬虫工程师无意义的活

30岁的年龄;这个年龄大家都是成年人;都是做父母的年龄了;你再工位上的心态会发生很大变化的; 爬虫工程师基本都是如此;社会最low的一帮连销售都做不了的;单子都开不出来的然后转行做爬虫工程师的;这样的人基本不太和社会接触; 你作为爬虫初级工程师就敲着键盘然后解析着html;…...

DeepSeek 关联公司公布新型数据采集专利 提升数据采集效率与质量

4 月 1 日&#xff0c;国家知识产权局公布了一项由 DeepSeek 关联公司杭州深度求索人工智能基础技术研究有限公司申请的专利&#xff0c;名为 “一种广度数据采集的方法及其系统”&#xff0c;公开号为 CN 119739917 A&#xff0c;申请日期可追溯至 2024 年 12 月。此专利的发布…...

实际犯错以及复盘1

Ds1302 需要两个 一个Set_Rtc 一个Read_Rtc : 本质 read是 85-2i 的 写入是84-2i 然后 写入的时候 是需要对 0x8e 进行 0x00 和0x80进行解开和 锁定的开头结尾。 使用的时候 赋值给ucRtc[i] 然后 主函数使用的时候 需要直接写个(ucRtc) 因为unsigned char* 默认的…...

初探:简道云系统架构及原理

一、系统架构概述 简道云作为一款低代码开发平台&#xff0c;其架构设计以模块化和云端协同为核心&#xff0c;主要分为以下层次&#xff1a; 1. 前端层 可视化界面&#xff1a;基于Web的拖拽式表单设计器&#xff0c;支持动态渲染&#xff08;React/Vue框架&#xff09;。多…...

Nginx负载均衡时如何为指定ip配置固定服务器

大家在用Nginx做负载均衡时&#xff0c;一般是采用默认的weight权重指定或默认的平均分配实现后端服务器的路由&#xff0c;还有一种做法是通过ip_hash来自动计算进行后端服务器的路由&#xff0c;但最近遇到一个问题&#xff0c;就是希望大部分用户采用ip_hash自动分配后端服务…...

玩转MCP:用百度热搜采集案例快速上手并接入cline

MCP的大火&#xff0c;让MCP服务器开发也变得热门&#xff0c;上一篇文章: 手搓MCP客户端&服务端&#xff1a;从零到实战极速了解MCP是什么&#xff1f; 手搓了一个极其简单的小场景的MCP实战案例&#xff0c;详细的安装环境及操作步骤已经讲过了&#xff0c;本文不在重复…...

003集——《利用 C# 与 AutoCAD API 开发 WPF 随机圆生成插件》(侧栏菜单+WPF窗体和控件+MVVM)

本案例聚焦于开发一款特色鲜明的 AutoCAD 插件。其核心功能在于&#xff0c;用户在精心设计的 WPF 控件界面中输入期望生成圆的数量&#xff0c;完成输入后&#xff0c;当用户点击 “生成” 按钮&#xff0c;一系列联动操作随即展开。通过数据绑定与命令绑定这一精妙机制&#…...

设计模式简述(十)责任链模式

责任链模式 描述基本使用使用 描述 如果一个请求要经过多个类似或相关处理器的处理。 可以考虑将这些处理器添加到一个链上&#xff0c;让请求逐个经过这些处理器进行处理。 通常&#xff0c;在一个业务场景下会对整个责任链进行初始化&#xff0c;确定这个链上有哪些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 查看依赖包的版本 项目基本信息记录 项目标识&#xff1a;记录项目名称&#xff08;name 字段&#xff09;、版本号&#xff08;version 字段&#xff09;、描述&#xff08;description 字段&#xff09;等基础信息&#xff0c;方便识别和管理项目。例如&…...

从奖励到最优决策:动作价值函数与价值学习

从奖励到最优决策&#xff1a;动作价值函数与价值学习 价值学习动作价值函数对 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:采用多模式大型语言模型的车对车协同自动驾驶

原文地址&#xff1a; 2502.09980https://arxiv.org/pdf/2502.09980 论文翻译&#xff1a; V2V-LLM: Vehicle-to-Vehicle Cooperative Autonomous Driving with Multi-Modal Large Language Models V2V-LLM&#xff1a;采用多模式大型语言模型的车对车协同自动驾驶 摘要&#…...

NLP 梳理01 — 文本预处理和分词

文章目录 一、说明二、文本预处理概述2.1 为什么要预处理文本&#xff1f;2.2 文本预处理的常见步骤2.3 什么是令牌化&#xff1f;2.4 为什么令牌化很重要&#xff1f; 三、分词类型四、用于分词化的工具和库五、实际实施六、编写函数以对文本进行标记七、结论 一、说明 本文总…...

Windows11 优雅的停止更新、禁止更新

网上有很多关闭自动更新的方法&#xff0c;改注册表、修改组策略编辑器、禁用Windows Update等等&#xff0c;大同小异&#xff0c;但最后奏效的寥寥无几&#xff0c;今天给大家带来另一种关闭win11自动更新的方法&#xff0c;亲测有效&#xff01; 1、winR 打开运行窗口&…...

Kafka 中的 offset 提交问题

手动提交和自动提交 我们来一次性理清楚&#xff1a;Kafka 中的自动提交 vs 手动提交&#xff0c;到底区别在哪&#xff0c;怎么用&#xff0c;什么场景适合用哪个&#x1f447; &#x1f9e0; 一句话总结 ✅ 自动提交&#xff1a;Kafka 每隔一段时间自动提交 offset ✅ 手动…...

PowerBI窗口函数与视觉计算

文章目录 一、 窗口函数1.1 OFFSET&#xff08;动态查询、求连续值&#xff09;1.1.1 不使用orderBy1.1.2 使用orderBy1.1.3 统计连续值的最大出现次数&#xff08;待补&#xff09; 1.2 INDEX&#xff08;静态查询&#xff09;1.3 WINDOW&#xff08;滚动求和、累计求和、帕累…...

代码随想录算法训练营Day22

回溯知识 力扣77.组合【medium】 一、回溯知识 1、定义 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 2、回溯法的效率 回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案…...

几种常见的HTTP方法之GET和POST

如大家所了解的&#xff0c;每条 HTTP 请求报文都必须包含一个请求方法&#xff0c;这个方法会告诉服务器要执行什么操作&#xff08;例如获取一个 Web 页面、运行一个网关程序、删除一个文件等&#xff09;。常见的几种 HTTP 方法如下&#xff1a; GET&#xff1a; 请求指定的…...

Nginx之https重定向为http

为了将Nginx中443端口的请求重定向到80端口&#xff0c;你可以按照以下步骤进行操作&#xff1a; ‌确认Nginx已经正确安装并运行‌&#xff1a; 确保Nginx服务已经在你的系统上安装并运行。你可以通过运行以下命令来检查Nginx的状态&#xff08;具体命令可能因操作系统而异&a…...

落地DevOps文化:运维变革的正确打开方式

落地DevOps文化:运维变革的正确打开方式 DevOps,这个近年来被谈论得沸沸扬扬的概念,是企业数字化转型的一把钥匙。然而,很多公司虽然喊着“要上DevOps”,却苦于如何真正落地。而DevOps不仅仅是技术工具的堆砌,更是一种文化的重塑。从我的经历来看,DevOps实施的核心在于…...

《C++后端开发最全面试题-从入门到Offer》目录

当今科技行业对C++开发者的需求持续高涨,从金融科技到游戏开发,从嵌入式系统到高性能计算,C++凭借其卓越的性能和灵活性始终占据着关键地位。然而,成为一名优秀的C++工程师并非易事,不仅需要扎实的语言基础,还要掌握现代C++特性、设计模式、性能优化技巧以及各种工业级开…...

24统计建模国奖论文写作框架2(机器学习+自然语言处理类)(附原文《高校负面舆情成因与演化路径研究》)

一、引言 研究背景及意义 文献综述 研究内容与创新点 二、高校负面舆情热点现状分析 案例数据的获取与处理 高效负面舆情热点词频分析 高效负面舆情热点变化趋势分析 三、高校负面舆情成因分析 高校负面舆情变量的选取与赋值 基于QCA方法的高校负面舆情成因分析 四、…...

论文阅读笔记——Deformable Radial Kernel Splatting

DRK 论文 DRK&#xff08;可变形径向核&#xff09;的核心创新正是通过极坐标参数化与切平面投影&#xff0c;对传统3D高斯泼溅&#xff08;3D-GS&#xff09;进行了多维度的优化。 传统 3DGS 依赖径向对称的高斯核&#xff0c;只能表示平滑、各向同性的形状&#xff08;球体、…...

网络编程—TCP/IP模型(IP协议)

上篇文章&#xff1a; 网络编程—TCP/IP模型&#xff08;TCP协议&#xff09;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 项目的完整脚本模板​​&#xff0c;基于 NDK 工具链&#xff0c;支持自定义源文件编译为静态库/动态库/可执行文件&#xff1a; 1. 基础交叉编译脚本 (build_android.sh) bash 复制 #!/bin/bash# Android 交叉编译脚本 (arm64-…...

IS-IS-单区域的配置

一、IS-IS的概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种‌链路状态路由协议‌&#xff0c;最初设计用于‌OSI&#xff08;Open Systems Interconnection&#xff09;参考模型‌的网络层&#xff08;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 模式 下有所不同&#xff0c;主要体现在 领导选举 和 集群元数据管理 的方式上。下面详细介绍这两种模式下 Kafka 如何进行选举机制。 1. Zookeeper 模式下的选举机制 在早期的 Kafka 架构中&#xff0c;集群的元数据管理和选举机…...

FreeRTOS移植笔记:让操作系统在你的硬件上跑起来

一、为什么需要移植&#xff1f; FreeRTOS就像一套"操作系统积木"&#xff0c;但不同硬件平台&#xff08;如STM32、ESP32、AVR等&#xff09;的CPU架构和外设差异大&#xff0c;需要针对目标硬件做适配配置。移植工作就是让FreeRTOS能正确管理你的硬件资源。 二、…...

设计模式简述(十二)策略模式

策略模式 描述基本使用使用传统策略模式的缺陷以及规避方法 枚举策略描述基本使用使用 描述 定义一组策略&#xff0c;并将其封装起来到一个策略上下文中。 由调用者决定应该使用哪种策略&#xff0c;并且可以动态替换 基本使用 定义策略接口 public interface IStrategy {…...

如何在idea中快速搭建一个Spring Boot项目?

文章目录 前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热启动&#xff08;热部署&#xff09;结语 前言 Spring Boot 凭借其便捷的开发特性&#xff0c;极大提升了开发效率&#xff0c;为 Java 开发工作带来诸多便利。许多大伙伴希望快速…...

【注解简化配置的原理是什么】

注解&#xff08;Annotation&#xff09;简化配置的核心原理是将原本分散在外部文件&#xff08;如XML、properties&#xff09;中的元数据直接内嵌到代码中&#xff0c;通过声明式编程让框架或工具自动处理这些元数据&#xff0c;从而减少手动配置的复杂度。以下是其实现原理的…...