C语言字符串使用详解

文章详细介绍了C语言中字符串的初始化方式,包括字符数组和字符指针的使用,以及字符串结束符的作用。还讨论了获取字符串长度的strlen函数,以及字符串复制strcpy、strncpy,连接strcat、strncat和格式化写入字符串sprintf、snprintf的方法。最后,通过示例展示了如何处理字符串数组和别名情况。
摘要由CSDN通过智能技术生成

1.字符串初始化

C语言和C++不同,没有专门的字符串类型(string)。C语言中的字符串更多理解为char类型的数组。
初始化方式:

  • char str[] = {“my string”}
    • char str[16] = {“my string”}
  • char charArray[] = {‘M’,‘y’,‘s’,‘t’,‘r’,‘i’,‘n’,‘g’};
    • char charArray[] = “My string”;
  • char *string = “my string”
    • 在遍历该string时,可以使用*string++的方式来循环遍历每一个字符
  • 声明为数组的变量,是不能先申明,再用常量赋值的
    • 一下两种方式都不合规
    char str[LENGTH];
    str = "test";
    str = {'t', 'e', 's', 't'};
    

字符串数组初始化方式:

  • char str[][] = {“my”,“string”};

字符串打印:

  • 单个字符打印 printf("%c\n",charArray[i])
  • 字符串打印 printf("%\n",charArray)

2.字符串结束符'\0'

  • c语言会自动添加一个字符串结束符'\0'0的转义字符
  • 字符串按照单个字符打印时,结束符’\0’一般都是显示空白,抬行
    void test1(void)
    {
        char charArray[] = {'M','y','s','t','r','i','n','g'};
        int len = strlen(charArray);
        for(int i = 0; i < len + 1; i++){
            printf("%c\n",charArray[i]);
        }
    }
    
    • 打印结果:
    M
    y
    s
    t
    r
    i
    n
    g
    
    
  • 字符串结束符是在字符串结尾自动加的,不需要手动加,初始化时手动添加'\0'也没有影响

3.字符串操作

  • 获取字符串长度
    • strlen
    • sizeof
      • strlen统计字符串中有效字符长度(不包含’\0’),库函数
      • sizeof测试数组长度,包含’\0’,单目运算符
  • 字符串复制
    • char *strcpy(char *dst , char const *src);
      • 必须保证dst的长度比src
    • char *strncpy(char *dst , char const *src , size_t len);
      • 如果 strlen(src) > len,则只有 len 个字符被复制到 dst 中去,此时 dst 将不会以 NUL 字节结尾
        • 也就是说,strncpy调用的结果可能不是一个字符串,无结束符
      • 如果 strlen(src) < len,则 src 中的字符全被复制到 dst 中去,dst 中剩余的部分用 NUL 填充
  • 字符串连接
    • char *strcat(char *dst,char const *src);
      • 函数 strcat 将参数 src 字符串连接到参数 dst 字符串的后面
      • 必须保证 dst 的剩余空间足够存放下 src 整个字符串
    • char *strncat(char *dst , char const *src , size_t len);
      • strncat 函数从 src 中最多复制 len 个字符到目标数组 dst 后面,
      • strncat 总是在结果字符串后面添加一个 NUL 字节
  • 字符串写入
  • int sprintf(char *str, const char &format, ...);
    • 把格式化的数据写入字符串str中,返回值为写入str的字节数,自动添加‘\0’并不计入字节数
    • 实际写入的字符数要比返回值多1
  • int snprintf(char *str, size_t size, const char *format, ...);
    • 把格式化的数据写入字符串str中,最多写size个字节,自动添加‘\0’;
    • 返回值为写入str的字节数,不包括结束字符‘\0’

字符串打印列对齐

  • 制表符\t
    • 具体补齐长度和系统格式有关(4或者8个字符宽度)
    • 可以多加几个\t组合使用 \t\t\t
  • 占用宽度控制
    • 左对齐
      • %-nC
      • C为打印格式,例如%10d, %12f, %5c, %20s
    • 右对齐
      • %nC

应用例子

本例中,构造一个名字数组,容量为3。针对部分可能存在别名情况,设计用两个字符串组合成一个新串保存在名字数组中。
要点:

  • name数组形式为字符指针串数组,实际上理解为字符串数组。所以在初始化时,需要构造字符指针去初始化
    • 本例中实现方法为malloc去开辟内存char*类型地址,直接用snprintf函数写入字符串到该地址
    • 针对别名,直接把两个串都保存到一块空间中,snprint会自动添加字符结束符’\0’,且会把结束符长度加到返回值中
      • strlen
  • base_name为字符串数组,使用二维char数组方法构造
  • 打印时,printf函数在遇到字符串结束符’\0’时,就会停止打印
    • 为了打印第二个字串,需要使用指针指向第二个字串的起始位置
void test2(void)
{
    char *name[MAX_STUDENT_NUM] = {0};
    char *cur_name = NULL;
	char *source_name = NULL;
    int other_name[3] = {0,0,1};
    char base_name[][8] = {
        "bob",
        "tom",
        "jem",
    };

    for(int i = 0; i < MAX_STUDENT_NUM; i++)
    {
        int len = 0;
        source_name =  (char *)malloc(NAME_LENGTH * 2);
        cur_name = source_name;
        if(other_name[i]  ==  0)
        {
            len  =  snprintf(cur_name, NAME_LENGTH, "name[%s_%d]" ,base_name[i], i);
        } else {
            len  =  snprintf(cur_name, NAME_LENGTH, "name[%s_%d]" ,base_name[i], i);
            cur_name += (len + 1); //这里加1的目的时确保,下一个串没有占用上个字串的'\0'
            len  =  snprintf(cur_name, NAME_LENGTH, "name[%s_%d]" ,base_name[i], i+1);   
        }
        name[i] = source_name;
    }

    for(int i = 0; i < MAX_STUDENT_NUM; i++)
    {
        cur_name =  name[i];
        printf("name is : %s\n", name[i]);
    }

    printf("=============\n");

    for(int i = 0; i < MAX_STUDENT_NUM; i++)
    {
        cur_name =  name[i];
        if(other_name[i]  ==  0)
        {
            printf("name is : %s\n", name[i]);
        } else {
            printf("name is : %s\n", name[i]);
            cur_name += (strlen(cur_name)  + 1);  //+1和上面写入的+1对应
            printf("name is : %s\n", cur_name);
        }
    }
}

结果:

name is : name[bob_0]
name is : name[tom_1]
name is : name[jem_2]
=============
name is : name[bob_0]
name is : name[tom_1]
name is : name[jem_2]
name is : name[jem_3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值