长度受限和其他字符串函数

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

前言

       本文介绍一下C语言字符串库函数中长度受限的字符串函数和一些其他字符串函数。

       新手一个,水平比较低,还请包涵。

长度受限的字符串函数

     还有一类长度受限的字符串函数,因其对操作的字符串长度由用户来规定,使用起来相对安全。本质上就是比长度不受限的函数要多了一个字符个数的参数num来限定操作的字符串长度,别的地方并无不同。

strncpy函数

相关描述

函数原型:char* strncpy ( char* destination, const char* source, size_t num );

函数功能:从字符串中复制字符

     拷贝num个字符从源字符串到目标空间。 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

     如果源长于num,则不会在目标末尾隐式追加空字符。因此,在这种情况下,不应将目标视为空终止的C字符串(读取它会使溢出)。

     目标和源不得重叠。

参数说明:

     目标空间

               指向要在其中复制内容的目标数组的指针。

      

               要复制的 C 字符串。

      数字

               要从源复制的最大字符数。

               size_t是无符号整数类型。

返回类型:char*

示例

       当源字符串长度更大时:

image.png

       当源字符串长度更小时:

image.png

模拟实现

char* MyStrncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);

	char* ret = dest;

	while (num && (*dest++ = *src++))
	{
		num--;
	}

	if (num > 0)
	{
		while (num--)
		{
			*dest++ = '\0';
		}
	}

	return ret;
}

strncat函数

相关描述

函数原型:char strncat (char destination, const char* source, size_t num);

函数功能: 从字符串追加字符

               将num个字符从源字符串追加到目标空间的末尾。

               如果源字符串的长度小于num,则仅追加终止空字符之前的内容。

               无论源字符串长度大于还是小于num,追加完后会给末尾再加上一个'\0'。

参数说明

       目标空间

                指向要在其中复制内容的目标数组的指针。

        

               要追加的 C 字符串。

        数字

               要从源字符串追加的最大字符数。

               size_t是无符号整数类型。

返回类型:char*

示例

        源字符串较短时: 

image.png

        源字符串较长时:

image.png

模拟实现

char* MyStrncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);

	char* ret = dest;

	while (*(++dest));

	while (num && (*dest++ = *src++))
	{
		num--;
	}

	if (0 == num && '\0' != *src)
	{
		*dest = '\0';
	}

	return ret;
}

strncmp函数

相关描述

函数原型:int strncmp ( const char* str1, const char* str2, size_t num );

函数功能

          比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

          比较的是指定数目的字符,也就是前num个字符才发生比较。

参数说明:

        str1               

        str2

               要相互比较的 C 字符串。

        num

                要从源字符串追加的最大字符数。

                size_t是无符号整数类型。

返回类型:int

image.png

示例

image.png

其他字符串函数

strtok函数

相关描述

函数原型:char* strtok (char* str, const char* sep );

参数说明:sep参数是个字符串,定义了用作分隔符的字符集合。

                第一个参数str指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。

函数功能:实际上是切割字符串,每次切一段。

                  strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

                  strtok函数可以多次使用:

                  当strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。

                  当strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 如果字符串中不存在更多的标记,则返回 NULL 指针。

                  若有多个相邻切割符相当于一个。

返回类型:char*

示例

image.png

image.png

strerror函数

相关描述

函数原型:char* strerror (int errnum);

函数功能:C语言的库函数,在执行失败时,都会设置错误码。

C语言设置了一个全局范围的错误码存放变量——errno,所在头文件为<errno.h>

strerror函数返回错误码所对应的错误信息。

返回类型:char*

示例

#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{
     FILE * pFile;
     pFile = fopen ("unexist.ent","r");
     if (pFile == NULL)
     printf ("Error opening file unexist.ent: %s\n",strerror(errno));
    //errno存放的是最新的错误码
     return 0;
}

atoi函数

所在头文件:<stdlib.>

函数原型:int atoi(const char *str);

函数功能:把字符串转换成整型数,比如说把"123"转换成123。

函数说明

                  atoi()会扫描参数str字符串,跳过前面的空格字符串,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串‘\0’时才结束转换,并将结果返回,返回转换后的整型数。

                  如果字符串中的第一个非空格字符序列不是有效的整数(其他字符),或字符串全为空或只包含空格字符,则不会执行转换并返回零。

返回类型:int

示例

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

int main()
{
    char str1[] = "  1234";
    char str2[] = "abc123";
    char str3[] = "   ";
    char str4[] = "\0";
    char str5[] = "  123  abc";

    int a = atoi(str1);
    int b = atoi(str2);
    int c = atoi(str3);
    int d = atoi(str4);
    int e = atoi(str5);
 
    printf("%d  %d  %d  %d  %d\n", a, b, c, d, e);
    return 0;
}

image.png

模拟实现

注意事项:

需要判断:

1.空指针

2.空字符串

3.空格

4.+-

5.越界

6.非数字字符

7.返回值是否合法

#include<ctype.h>
#include<limits.h>
#include<assert.h>

enum status
{
    INVALID,
    VALID
};

enum status g_nSta = INVALID;//判断返回值是否合法

int MyAtoi(const char* str)
{
    assert(str);//判断空指针

    if (*str == '\0')//判断空串
        return 0;

    while (isspace(*str))//跳过空格
    {
        str++;
    }
    
    int flag = 1;
    long long ret = 0;

    if (*str == '+')//判断+-
    {
        flag = 1;
        str++;
    }
    else if(*str == '-')
    {
        flag = -1;
        str++;
    }

    while (*str)
    {
        if (isdigit(*str))//判断是不是数字字符
        {
            ret = ret * 10 + flag * (*str - '0');//数字字符转数字

            if (ret > INT_MAX || ret < INT_MIN)//判断是否越界
            {
                return 0;
            }
        }
        else
        {
            g_nSta = VALID;
            return (int)ret;
        }
        str++;
    }

    g_nSta = VALID;

    return (int)ret;
}