Linux C语言 35-字符串处理补充

Linux C语言 35-字符串处理补充

本节关键字:C语言 字符串处理 内存处理
相关C库函数:printf、sprintf、snprintf、scanf、sscanf、strcmp、strstr、strcpy、atoi、atol、atoll、memcpy、memcmp、memmove等

从标准stdin读取格式化输入

#include <stdio.h>
int scanf(const char *format, ...);
/**
@brief  从标准输入stdin读取格式化输入
@param  format 可以是:%c %d %f %o %s %u %x %p %[] %%等
@param  ... [可变参数](https://blog.csdn.net/qq_45157350/article/details/134600815)
@return 成功返回匹配和赋值的个数,失败返回EOF
*/

// 例程参考之前的文章:[Linux C语言 24-格式化操作](https://blog.csdn.net/qq_45157350/article/details/134594551)

从字符串读取格式化输入

#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
/**
@brief  从字符串读取格式化输入
@param  str C语言字符串
@param  format 可以是:%c %d %f %o %s %u %x %p %[] %%等
@param  ... [可变参数](https://blog.csdn.net/qq_45157350/article/details/134600815)
@return 成功返回匹配和赋值的个数,失败返回EOF
*/

后期出一篇单独的文章 Linux C语言 45-sscanf函数

格式化输出到标准输出stdout

#include <stdio.h>
int printf(const char *format, ...);
/**
@brief  格式化输出到标准输出stdout
@param  format 可以是:%c %d %f %o %s %u %x %p %[] %%等
@param  ... [可变参数](https://blog.csdn.net/qq_45157350/article/details/134600815)
@return 成功返回写入的字符总数,失败返回负数
*/

// 例程参考之前的文章:[Linux C语言 24-格式化操作](https://blog.csdn.net/qq_45157350/article/details/134594551)

格式化输出到str指向的字符串

#include <stdio.h>
int sprintf(char *str, const char *format, ...);
/**
@brief  格式化输出到str指向的字符串
@param  str 存储格式化结果的缓冲区
@param  format 可以是:%c %d %f %o %s %u %x %p %[] %%等
@param  ... [可变参数](https://blog.csdn.net/qq_45157350/article/details/134600815)
@return 成功返回写入的字符总数(不包括字符串追加在字符串末尾的空字符),失败返回负数
*/

// 例程参考之前的文章:[Linux C语言 24-格式化操作](https://blog.csdn.net/qq_45157350/article/details/134594551)
#include <stdio.h>
int snprintf(char *str, size_t size, const char *format, ...);
/**
@brief  格式化输出到str指向的字符串,限制输出的字符数,避免缓冲区溢出,最多写入size-1个字符
@param  str 存储格式化结果的缓冲区
@param  format 可以是:%c %d %f %o %s %u %x %p %[] %%等
@param  ... [可变参数](https://blog.csdn.net/qq_45157350/article/details/134600815)
@return 成功返回写入缓冲区的字符总数(不包括字符串追加在字符串末尾的空字符),失败返回负数
*/

// 复习一下 # 的作用
#define toStr(a) #a

void tSnprintf(void)
{
    int no = 1713080405;
    char name[] = "Zhangsan";
    int sex = 1;
    char language[] = "Chinese";
    float score = 99.99;
    
    char sText[512];
    
    memset(sText, 0, sizeof(sText));
    sprintf(sText, " %s:%d\n %s:%s\n %s:%s\n %s:%s\n %s:%.02f\n", 
        toStr(no), no, 
        toStr(name), name,
        toStr(sex), sex ? "man" : "women", // 复习一下三目运算符?
        toStr(language), language,
        toStr(score), score);
    
    printf("%s\n", sText);
}

计算字符串长度

#include <string.h>
size_t strlen(const char *s);
/**
@brief  计算字符串的长度,直到空结束符,但不包括空结束符('\0')
@param  s 要计算长度的字符串
@return 返回字符串的长度(不包含字符串结束符)
*/

void tStrlen(void)
{
    char str1[] = "abcdefg";
    char str2[] = "12345\06789";
    char str3[] = "a1 b1 c3 ? ~ @ ";
    
    printf("strlen(str1)=%d, str1: %s\n", strlen(str1), str1);
    printf("strlen(str2)=%d, str2: %s\n", strlen(str2), str2); // 有发现什么异常吗?
    printf("strlen(str3)=%d, str3: %s\n", strlen(str3), str3);
}

字符串比较

#include <string.h>
int strcmp(const char *s1, const char *s2);
/**
@brief  比较字符串s1与s2,从第一个字符开始比,直到不相等的字符结束
@param  s1 第一个字符串
@param  s2 第二个字符串
@return s1<s2 返回值负数;s1>s2 返回正数;s1=s2 返回0
*/

void tStrcmp(void)
{
    char str1[] = "Hello, i'm Lihua";
    char str2[] = "Hello, i'm Lihuan";
    char str3[] = "Hello";
    char str4[] = "Hello\09";
    
    printf("%d\n", strcmp(str1, str2));
    printf("%d\n", strcmp(str1, str3));
    printf("%d\n", strcmp(str3, str4));    // 注意!
    printf("%d\n", strcmp(str3, str2));
}
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
/**
@brief  比较字符串s1与s2的前n个字符
@param  s1 第一个字符串
@param  s2 第二个字符串
@param  n 要比较的最大字符数
@return s1<s2 返回值负数;s1>s2 返回正数;s1=s2 返回0
*/

void tStrncmp(void)
{
    char str1[] = "Hello, i'm Lihua";
    char str2[] = "Hello, i'm Lihuan";
    char str3[] = "Hello";
    char str4[] = "Hello\09";
    
    printf("%d\n", strncmp(str1, str2, 6));
    printf("%d\n", strncmp(str1, str3, 6));
    printf("%d\n", strncmp(str3, str4, 6));    // 注意!
    printf("%d\n", strncmp(str3, str2, 6));
}

字符串查找

#include <string.h>
char *strstr(const char *haystack, const char *needle);
/**
@brief  在字符串haystack中查找字符串needle第一次出现的位置,不包含终止符'\0'
@param  haystack 被检索的字符串
@param  needle 需要检索的短字符串
@return 找到返回字符串needle第一次出现的位置,未找到返回NULL
*/

void tStrstr(void)
{
    char haystack[] = "Hello Hi DD MM XoX String Name OoO !!!!";
    char needle[] = "OoO";
    
    printf("%s\n", strstr(haystack, needle));
}

字符串拷贝

#include <string.h>
char *strcpy(char *dest, const char *src);
/**
@brief  将字符串src拷贝到dest中,如果字符串src的长度大于字符串dest可能会造成缓冲溢出
@param  dest 存储拷贝内容的数组
@param  src 被拷贝的字符串
@return 返回一个指向最终目标字符串dest的指针
*/

void tStrcpy(void)
{
    char dest[128] = {0};
    char src[] = "OoO";
    
    printf("%s\n", strcpy(dest, src));
}
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
/**
@brief  将字符串src的前n个字符拷贝到dest中,dest的剩余部分用空字节填充
@param  dest 存储拷贝内容的数组
@param  src 被拷贝的字符串
@param  n 要从源字符串中拷贝的字节数
@return 返回一个指向最终目标字符串dest的指针
*/

void tStrncpy(void)
{
    char dest[128] = {0};
    char src[] = "OoO n|n";
    
    printf("%s\n", strncpy(dest, src, 3));
}

字符串拼接

#include <string.h>
char *strcat(char *dest, const char *src);
/**
@brief  把src指向的字符串追加到dest指向的字符串结尾
@param  dest 存储拷贝内容的数组
@param  src 被拷贝的字符串,该字符串不会覆盖目标字符串
@return 返回一个指向最终目标字符串dest的指针
*/

void tStrcat(void)
{
    char dest[128] = {0};
    char src[] = "OoO n|n";
    
    printf("%s\n", strcat(dest, src));
}
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
/**
@brief  把src指向字符串的前n个字符追加到dest指向的字符串结尾
@param  dest 存储拷贝内容的数组
@param  src 被拷贝的字符串,该字符串不会覆盖目标字符串
@return 返回一个指向最终目标字符串dest的指针
*/

void tStrncat(void)
{
    char dest[128] = {0};
    char src[] = "OoO n|n";
    
    printf("%s\n", strncat(dest, src, 3));
}

字符串分割

#include <string.h>
char *strtok(char *str, const char *delim);
/**
@brief  分解字符串str为一组字符串,delim为分隔符
@param  str 要被分解的字符串
@param  delim 包含分隔符的C字符串
@return 返回被分解的第一个子字符串,如果没有可检索的字符串,则返回空指针NULL
*/

void tStrtok(void)
{
    char buffer[] = "Chinese man 25,C language 99,there strtok_r,test";
    char *token;
    
    token = strtok(str, ",");
    
    while (token)
        printf("%s\n", token=strtok(NULL, ","));
}
#include <string.h>
char *strtok_r(char *str, const char *delim, char **saveptr);
/**
@brief  分解字符串(linux平台下strtok函数的线程安全版)
@param  str 要被分解的字符串
@param  delim 分隔符C字符串
@param  saveptr 保存切分时的上下文,应对连续调用分解相同源字符串
@return 返回被分解的第一个子字符串,如果没有可检索的字符串,则返回空指针NULL

第一次调用strtok_r时,str参数必须指向待提取的字符串,saveptr参数的值可以忽略。
连续调用时,str赋值为NULL,saveptr为上次调用后返回的值,不要修改。
一系列不同的字符串可能会同时连续调用strtok_r进行提取,要为不同的调用传递不同的saveptr参数。
strtok_r实际上就是将strtok内部隐式保存的this指针,以参数的形式与函数外部进行交互。
由调用者进行传递、保存甚至是修改。需要调用者在连续切分相同源字符串时,除了将str参数赋值为NULL,还要传递上次切分时保存下的saveptr。
*/

void tStrtok_r(void)
{
    int i, in = 0;
    char buffer[] = "Chinese man 25,C language 99,there strtok_r test";
    char *p[20];
    char *buf = buffer;
    char *outer_ptr = NULL;
    char *inner_ptr = NULL;
    
    printf("source C string is: %s\n", buffer);
    
    while ((p[in] = strtok_r(buf, ",", &outer_ptr)) != NULL)
    {
        buf = p[in];
        while ((p[in] = strtok_r(buf, " ", &inner_ptr)) != NULL)
        {
            in++;
            buf = NULL;
        }
        buf = NULL;
    }
    
    printf("strtok_r() get %d strings: \n", in);
    for (i = 0; i < in; i++)
        printf("No(%d) -> %s\n", i, p[i]);
}

获取错误码的字符串描述

#include <string.h>
char *strerror(int errnum);
/**
@brief  从内部数组中搜索错误码errnum,并返回一个指向错误消息字符串的指针,字符串内容取决于平台和编译器
@param  errnum 要查询的错误码,通常是全局变量errno
@return 返回一个指向错误码描述的字符串指针
*/

#include <error.h>
void tStrerror(void)
{
    printf("%s\n", strerror(errno));
}

内存拷贝

#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
/**
@brief  从存储区src复制n个字节到存储区dest
@param  dest 存储复制内容的目标数组,类型强制转换为void*
@param  src 要复制的内容,类型强转为void*
@param  n 要复制的字节数
@return 返回指向目标存储区dest的指针
*/

void tMemcpy(void)
{
    char dest[1024];
    char src[] = "memcpy test.";
    
    memset(dest, 0, sizeof(dest));
    printf("1: %s\n", dest);
    memcpy(dest, src, strlen(src));
    printf("2: %s\n", dest);
}

内存比较

#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
/**
@brief  比较s1和s2的前n个字节
@param  s1 指向内存区域的指针
@param  s2 指向内存区域的指针
@param  n 要比较的字节数
@return s1<s2返回负数;s1>s2返回正数;s1=s2返回0
*/

void tMemcmp(void)
{
    char str1[] = "Hello, i'm Lihua";
    char str2[] = "Hello, i'm Lihuan";
    char str3[] = "Hello";
    char str4[] = "Hello\09";
    
    printf("%d\n", strncmp(str1, str2, 6));
    printf("%d\n", strncmp(str1, str3, 6));
    printf("%d\n", strncmp(str3, str4, 6));
    printf("%d\n", strncmp(str3, str2, 6));
}

内存移动(拷贝)

#include <string.h>
void *memmove(void *dest, const void *src, size_t n);
/**
@brief  将src的前n个字符复制到dest,区域重叠时也能避免内容被覆盖,保证内容拷贝成功
@param  dest 指针,指向存储复制内容的目标内存区域,类型强转为void*
@param  src 指针,指向要复制的数据内存区域,类型强转为void*
@param  n 要复制的字节数
@return 返回指向目标存储区dest的指针
*/

void tMemmove(void)
{
    char dest[] = "abcdefghijklmnopqrstuvwxyz";
    char *src = dest + 5;
    
    printf("dest: %s\n", dest);
    printf("%s\n", memmove(dest, src, strlen(src));
}

字符串与整型的转换

#include <stdlib.h>
int atoi(const char *nptr);
/**
@brief  把参数 str 所指向的字符串转换为一个int型的整数
@param  nptr 要被转换为整数的字符串
@return 成功返回转换后的整数,失败返回0
*/

void tAtoi(void)
{
    char nptr[] = "2234567890";
    
    printf("%d\n", atoi(nptr));
}
#include <stdlib.h>
long atol(const char *nptr);
/**
@brief  把参数 str 所指向的字符串转换为一个long int型的长整数
@param  nptr 要被转换为整数的字符串
@return 成功返回转换后的整数,失败返回0
*/

void tAtol(void)
{
    char nptr[] = "2234567890";
    
    printf("%ld\n", atol(nptr));
}
#include <stdlib.h>
long long atoll(const char *nptr);
/**
@brief  把参数 str 所指向的字符串转换为一个long long int型的长整数(64位)
@param  nptr 要被转换为整数的字符串
@return 成功返回转换后的整数,失败返回0
*/

void tAtoll(void)
{
    char nptr[] = "2234567890";
    
    printf("%lld\n", atoll(nptr));
}
#include <stdlib.h>
long long atoq(const char *nptr);
/**
@brief  把参数 str 所指向的字符串转换为一个long long int型的长整数(64位),是atoll()过去的名字
@param  nptr 要被转换为整数的字符串
@return 成功返回转换后的整数,失败返回0
*/
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值