首页 > 其他分享 >C语言中的字符串操作函数

C语言中的字符串操作函数

时间:2024-12-13 15:32:11浏览次数:3  
标签:函数 strtok C语言 char printf 字符串 World Hello

此篇文章在2024年10月29日被记录

盘点C语言中的字符串操作函数

1、字符串复制和连接

#include <stdio.h>
#include <string.h>

int main() {
    // strcpy
    char src1[] = "Hello";
    char dest1[20];
    strcpy(dest1, src1);
    printf("strcpy: %s\n", dest1);

    // strncpy
    char src2[] = "World";
    char dest2[20];
    strncpy(dest2, src2, 3);
    dest2[3] = '\0'; // 确保字符串以 null 结尾
    printf("strncpy: %s\n", dest2);

    // strcat
    char dest3[20] = "Hello";
    strcat(dest3, " World");
    printf("strcat: %s\n", dest3);

    // strncat
    char dest4[20] = "Hello";
    strncat(dest4, " World", 3);
    printf("strncat: %s\n", dest4);

    return 0;
}

输出:

strcpy: Hello
strncpy: Wor
strcat: Hello World
strncat: Hello Wo

注意项:

  • 在使用strcat时,需要确保拼接的字符串后方有足够的内存

2、字符串比较

#include <stdio.h>
#include <string.h>

int main() {
    // strcmp
    char str1[] = "Hello";
    char str2[] = "World";
    printf("strcmp: %d\n", strcmp(str1, str2));

    // strncmp
    char str3[] = "Hello";
    char str4[] = "Helium";
    printf("strncmp: %d\n", strncmp(str3, str4, 3));

    return 0;
}

输出:

strcmp: -15
strncmp: 0

strcmp 函数用于比较两个字符串,并返回一个整数值来表示它们的相对顺序。strcmp 的返回值有以下三种情况:

  • 负数:如果第一个字符串小于第二个字符串,strcmp 返回一个负数。这通常是因为在比较时,第一个字符串中第一个不同的字符的 ASCII 值小于第二个字符串中对应字符的 ASCII 值。
  • 零:如果两个字符串相等,strcmp 返回 0。这意味着两个字符串的长度相同,并且每个对应位置的字符都相同。
  • 正数:如果第一个字符串大于第二个字符串,strcmp 返回一个正数。这通常是因为在比较时,第一个字符串中第一个不同的字符的 ASCII 值大于第二个字符串中对应字符的 ASCII 值。

3、字符串长度

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello World";
    printf("strlen: %zu\n", strlen(str));
    return 0;
}

输出:

strlen: 11

注意项:

  • strlen是一个函数,用来查找一段内存最近的\0
  • sizeof是宏定义,在预处理阶段被替换为真值

4、字符串查找

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello World";

    // strchr
    char *result1 = strchr(str, 'o');
    if (result1) printf("strchr: %s\n", result1);

    // strrchr
    char *result2 = strrchr(str, 'o');
    if (result2) printf("strrchr: %s\n", result2);

    // strstr
    char *result3 = strstr(str, "World");
    if (result3) printf("strstr: %s\n", result3);

    // strpbrk
    char *result4 = strpbrk(str, "aeiou");
    if (result4) printf("strpbrk: %s\n", result4);

    // strspn
    size_t len1 = strspn(str, "Helo ");
    printf("strspn: %zu\n", len1);

    // strcspn
    size_t len2 = strcspn(str, "W");
    printf("strcspn: %zu\n", len2);

    return 0;
}

输出:

strchr: o World
strrchr: orld
strstr: World
strpbrk: ello World
strspn: 6
strcspn: 6

说明:

  • strchr:查找字符在字符串中的第一次出现。
  • strrchr:查找字符在字符串中的最后一次出现。
  • strstr:查找子字符串在字符串中的第一次出现。
  • strpbrk:查找字符串中任意字符集合的第一次出现。
  • strspn:计算字符串前缀中包含指定字符集合的长度。
  • strcspn:计算字符串前缀中不包含指定字符集合的长度。

5、字符串分割

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello,World,Test";
    char *token = strtok(str, ",");
    while (token != NULL) {
        printf("strtok: %s\n", token);
        token = strtok(NULL, ",");
    }
    return 0;
}

输出:

strtok: Hello
strtok: World
strtok: Test

说明:
strtok 函数在内部维护了一个静态指针,用于跟踪当前字符串分割的位置。这意味着第一次调用 strtok 时,它会保存字符串的起始位置,并在后续调用中继续从上次停止的位置开始处理。
strtok 的工作机制如下:

  • 第一次调用:当你第一次调用 strtok(str, ",") 时,strtok 会扫描 str 直到找到第一个分隔符(在这个例子中是逗号 ,)。然后,它会用 \0 替换这个分隔符,并返回第一个标记的指针。
  • 后续调用:在后续调用中,你传入 NULL 作为第一个参数,strtok 会从上次停止的位置继续扫描,寻找下一个分隔符。它会用 \0 替换找到的分隔符,并返回下一个标记的指针。
  • 结束条件:当没有更多的标记可提取时,strtok 返回 NULL。
    需要注意的是,由于 strtok 使用静态存储来保存状态,因此它不是线程安全的。如果你需要在多线程环境中使用类似的功能,可以考虑使用 strtok_r(POSIX 标准)或其他线程安全的字符串分割函数。
  • strtok 会修改原始字符串,因此如果需要保留原始字符串不变,应该先复制一份再进行分割。

6、内存操作

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char src[] = "Hello World";
    char dest[20];

    // memcpy
    memcpy(dest, src, strlen(src) + 1);
    printf("memcpy: %s\n", dest);

    // memmove (overlapping memory regions)
    memmove(dest + 6, dest, strlen(dest) + 1);
    printf("memmove: %s\n", dest);

    // memset
    memset(dest, '*', 5);
    dest[5] = '\0';
    printf("memset: %s\n", dest);

    // memcmp
    char str1[] = "abc";
    char str2[] = "abd";
    printf("memcmp: %d\n", memcmp(str1, str2, 3));

    // memchr
    char *result = memchr(src, 'W', strlen(src));
    if (result) {
        printf("memchr: %s\n", result);
    }

    // strdup
    char *duplicate = strdup(src);
    if (duplicate) {
        printf("strdup: %s\n", duplicate);
        free(duplicate); // Don't forget to free the allocated memory
    } else {
        printf("Failed to duplicate string.\n");
    }

    return 0;
}

输出:

memcpy: Hello World
memmove: Hello Hello World
memset: *****
memcmp: -1
memchr: World
strdup: Hello World

说明:
memcpy 和 memmove 都是用于在内存中复制数据的函数,但它们在处理重叠内存区域时有重要区别:

  • memcpy
    • 用途:用于复制一个内存块的数据到另一个内存块。
    • 重叠区域:memcpy 不安全用于重叠的内存区域。如果源和目标区域重叠,memcpy 的行为是未定义的。这意味着在这种情况下,memcpy 可能会导致数据损坏或其他不可预测的结果。
    • 性能:通常比 memmove 更快,因为它不需要处理重叠的情况。
  • memmove
    • 用途:同样用于复制一个内存块的数据到另一个内存块。
    • 重叠区域:memmove 安全用于重叠的内存区域。它会确保在复制过程中,源数据不会被覆盖,从而保证数据的正确性。
    • 性能:可能比 memcpy 稍慢,因为它需要处理重叠的情况以确保安全。
  • strdup
    • strdup会使用malloc申请内存块,使用完成后需要释放

标签:函数,strtok,C语言,char,printf,字符串,World,Hello
From: https://www.cnblogs.com/shumei52/p/18605080

相关文章

  • 在 .NET Core Web API 中接收 XML 格式的字符串
    [!info]以下内容基于ASP.NETCore3.1,更多版本详细内容请查看官方文档ASP.NETCore中的模型绑定|MicrosoftLearn配置WebAPI以接受XMLpublicvoidConfigureServices(IServiceCollectionservices){services.AddControllers().AddXmlSerializerForma......
  • 2024年华为OD机试真题-字符串分割-Java-OD统一考试(E卷)
    最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客     每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。题目描述:给定非空字符串s,将该......
  • 三维坐标旋转矩阵推导过程以及C语言实现
    此篇文章在2023年9月13日被记录前提:坐标使用右手坐标系,角度逆时针旋转为正。绕X轴旋转角度为俯仰角即Pitch绕Y轴旋转角度为偏航角即Yaw(Head)绕Z轴旋转角度为翻滚角即Roll1、平面二维坐标点的旋转根据三角函数关系,可以列出向量OP与OP'的坐标表示形式:x=|OP|•co......
  • 在windows下使用C语言进行图形编程 SDL2开发环境搭建
    此篇文章在2023年9月7日被记录你是否对C语言命令行黑框感到厌倦,今天来为你的C编程增加一些可视化窗口吧!1、windows下安装C编译器这对于一个开发者来说简直是太业余了,如果你是一个开发者,你的电脑上怎么会没有gcc呢,如果你是一个新手,可以转到这个链接:https://zhuanlan.zhihu.c......
  • 实变函数精解【33】
    文章目录可测函数可测函数列的收敛性1.**点态收敛与可测性**2.**一致收敛与可测性**3.**Lebesgue收敛定理(LebesgueDominatedConvergenceTheorem)**LebesgueDominatedConvergenceTheorem的陈述:4.**Fatou引理**总结:简单函数列1.**简单函数......
  • 初探C语言|实现井字棋游戏(超详解)
    文章目录前言正文**1.游戏基本规则****2.代码结构和实现****2.1初始化棋盘****2.2打印棋盘****2.3玩家和电脑的回合****2.4判断胜利或平局****2.5游戏主循环****2.6游戏菜单**总结与优化欢迎讨论:如有错误或不足,欢迎指正和建议,本人主打“听劝”。当然,如有疑......
  • 达梦DOTNET驱动DM.Provider8.3.1.30495存在空字符串插入变DBNull的问题
    达梦数据库的DOTNET驱动DM.Provider,这个版本8.3.1.30495有bug,会把空字符串改成DBNull处理,反编译代码发现Dm.DmSetValue.SetString方法中判断字符串长度==0就设置成DBNull。解决办法就是降低版本到8.3.1.28188。//Dm.DmSetValueusingSystem;usingSystem.Globalization;usi......
  • mysql 的row_count函数和found_rows函数【转】
    row_count()row_count函数返回的是当前连接中最近一次操作数据库的所影响的行数,增删改语句都能对它有效果。一定要是当前连接中,这个条件很重要!下面两条语句如果是用mysql客户端工具运行,一定要将两条sql全部选中一起运行才有效果。deletefromTwhereid=1;selectrow_count()......
  • 江科大STM32学习:01 C语言(2)指针
    1.指针简介指针Pointer是C语言的一个重要知识点,使用灵活,功能强大指针和底层硬件联系紧密(寄存器),使用指针可操作数据的地址,实现数据的间接访问2.计算机存储机制每个区域都是一个字节,线性分配下去,每个字节对应一个地址。注:一个字节是8bitinta=0x12345678;//十六进制,八......
  • 深入理解 JavaScript 柯里化: 提升函数的复用性和灵活性
    引言在JS编程中,函数是一等公民,具备了强大的灵活性和复用性。而柯里化作为一种高阶技术,可以进一步提升函数的复用性和灵活性。通过柯里化,可以大大简化函数的调用方式,并创建更加灵活和可复用的函数在本篇博客中,我们将深入探讨JS中柯里化的概念和原理,并......