C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(上)

简介: C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror

1 指针编程练习:

1.1 字符串左旋

实现一个函数,可以左旋字符串中的n个字符。

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

法一(移首补尾法):

 
#include<stdio.h>
#include<string.h>
#include<assert.h>
void string_left_rotate(char* str, int n)
{
    assert(str != NULL);
    int sum = strlen(str);
    for (int i = 0;i < n;i++)//旋转几个字符就循环几次
    {
        char tmp = *str;//1.把第一个字符存起来
        for (int j = 0;j < sum - 1;j++)
        {
            *(str + j) = *(str + j + 1);//2.把第一个后面的字符依次往前挪动一位
        }
        *(str + sum - 1) = tmp;//3.把第一个字符放到最后
    }
}
int main()
{
    char arr[20] = "ABCDEF";
    printf("%s\n", arr);
    int n = 0;
    scanf("%d", &n);
    string_left_rotate(arr, n);
    printf("%s\n", arr);
    return 0;
}

法二(三步翻转法):

 
#include<stdio.h>
#include<string.h>
#include<assert.h>
void reverse(char* left, char* right)//字符串逆置(翻转)函数
{
    assert(left != NULL);
    assert(right != NULL);
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void string_left_rotate(char* str, int n)
{
    int sum = strlen(str);
    assert(str!=NULL);
    //如ABCDEF  n=2
    reverse(str, str+n-1);//1.翻转要左旋的n个字符  BA CDEF
    reverse(str+n, str + sum - 1);//2.翻转要剩余的个字符 BA FEDC
    reverse(str, str + sum - 1);//3.整体翻转  CDEF AB
}
int main()
{
    char arr[20] = "ABCEDF";
    printf("%s\n", arr);
    int n = 0;
    scanf("%d", &n);
    string_left_rotate(arr, n);
    printf("%s\n", arr);
    return 0;
}

1.2 字符串旋转结果

字符串旋转

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定arr1 = AABCD和arr2 = BCDAA,返回1

给定arr1 = abcd和arr2 = ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

法一(暴力穷举法):

 
//法一(暴力穷举法):
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_string_rotate(char* str1, char* str2)
{
    //穷举str1所有左旋的结果,然后和str2比较(右旋是左旋的特殊形式)
    assert(str1 != NULL);
    assert(str2 != NULL);
    int sum = strlen(str1);
    for (int i = 0;i < sum;i++)//旋转str1所有的结果
    {
        char tmp = *str1;//1.把第一个字符存起来
        for (int j = 0;j < sum - 1;j++)
        {
            *(str1 + j) = *(str1 + j + 1);//2.把第一个后面的字符依次往前挪动一位
        }
        *(str1 + sum - 1) = tmp;//3.把第一个字符放到最后
 
        //旋转一个字符比较一次
        if (strcmp(str1, str2) == 0)
        {
            return 1;
        }
    }
    return 0;//所有结果比较完,没有就返回0
}
int main()
{
    char arr1[20] = "ABCDEF";
    char arr2[20] = "CDEFAB";
    if (is_string_rotate(arr1, arr2))//是就返回1
    {
        printf("yes\n");
    }
    else
    {
        printf("no\n");
    }
    return 0;
}

法二:

法二用到很多字符串函数,笔试时可以更好展现自己,而且效率更高了

这些字符串函数的详细介绍都放在下面文章了

 
//法二:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_string_rotate(char* str1, char* str2)
{
    assert(str1 != NULL);
    assert(str2 != NULL);
    if (strlen(str1) != strlen(str2))
    {
        return 0;   //长度不相等返回0
    }
 
    //1.给str1追加一个str1
    //如ABCDEF变成ABCDEFABCDEF  这样新字符串的其中6个就包含了原字符串旋转的所有可能
    strncat(str1, str1, strlen(str1));
    //字符串追加函数,在第一个参数后面追加第三个参数个第二个参数的字符串
    //(strcat不能给自己追加,strncat多最后一个参数)
    
    //2.比较str2是不是str1新字符串的子字符串(是的话就是str1原字符串旋转得来)
    char* ret = strstr(str1, str2);
    //判断第二个参数是否是第一个参数的子字符串
    //是的话返回第一个参数中子字符串的首地址,不是的话返回空指针
    //注意到如果长度不一样也是子字符串,不合题意,所以一开始判断长度
 
    return ret != NULL; //是空指针返回0,不是返回1
}
int main()
{
    char arr1[20] = "ABCDEF";
    char arr2[20] = "CDEFAB";
    if (is_string_rotate(arr1, arr2))//是就返回1
    {
        printf("yes\n");
    }
    else
    {
        printf("no\n");
    }
    return 0;
}

2 字符函数和字符串函数

下面讲的函数的头文件: string.h

重点介绍处理字符和字符串的库函数的使用和注意事项


求字符串长度

strlen

长度不受限制的字符串函数介绍

strcpy

strcat

strcmp


长度受限制的字符串函数介绍

strncpy

strncat

strncmp


字符串查找

strstr

strtok


错误信息报告

strerror

字符串操作:C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,

字符串通常放在常量字符串 中或者 字符数组 中。

字符串常量 适用于那些对它不做修改的字符串函数.


2.1 strlen三种实现

文档:size_t strlen ( const char * str );

1.字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数

(不包含 '\0')。

2.参数指向的字符串必须要以 '\0' 结束。

3.注意函数的返回值为size_t,是无符号的( 易错 )

代码演示:

 
#include <stdio.h>
#include <string.h>
int main()
{
    int len = strlen("abcdef");
    printf("%d\n", len);
    return 0;
}

要注意的地方:

 
#include<stdio.h>
#include<string.h>
int main()
{
    const char* str1 = "abcd";
    const char* str2 = "abcdef";
    if (strlen(str1) - strlen(str2) > 0)
    {
        printf("str1>str2\n");
    }
    else
    {
        printf("srt1<=str2\n");
    }
    return 0;
}
//输出str1>str2 因为无符号减无符号还是无符号 大于0
//用自己模拟的strlen就不会出现这种问题

strlen函数的模拟实现:(三种方法)

 
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strlen1(const char* str)//计数器版本
{
    assert(str != NULL);
    int count = 0;
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}
int my_strlen2(const char* str)//递归版本
{
    assert(str != NULL);
    if (*str != '\0')
        return 1 + my_strlen2(str + 1);
    else
        return 0;
}
//左下右上转圈地看
//my(hello)
//my(hello)     1+my(ello) =5
//my(ello)      1+my(llo)  =4
//my(llo)       1+my(lo)   =3
//my(lo)        1+my(o)    =2
//my(o)  return 1+my(\0)   =1
//my(\0):return 0;
int my_strlen3(const char* str)//指针减指针版本
{
    assert(str != NULL);
    char* ret = str;
    while (*ret != '\0')
    {
        ret++;
    }
    return ret - str;
}
int main()
{
    char arr[] = "hello";
    printf("%d\n", strlen(arr));
    printf("%d\n", my_strlen1(arr));
    printf("%d\n", my_strlen2(arr));
    printf("%d\n", my_strlen3(arr));
    return 0;
}

2.2 strcpy模拟实现

文档:char* strcpy(char * destination, const char * source );

Copies the C string pointed by source into the array pointed by destination, including the

terminating null character (and stopping at that point).

源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。

代码演示:

 
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[] = "abcdefghi";
    char arr2[] = "123";
    printf("拷贝前:%s\n", arr1);//拷贝前:abcdefghi
    strcpy(arr1, arr2); // 字符串拷贝(目标空间,源字符串)
    printf("拷贝后:%s\n", arr1);//拷贝后:123
    return 0;
}

strcpy函数的模拟实现

 
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
    assert(dest != NULL);
    assert(src != NULL);
    char* ret = dest;//让ret指向dest的起始地址
    while (*dest++ = *src++)//'\0'的ASCII码为0拷贝后跳出循环
    {
        ;
    }
    return ret;
}
int main()
{
    char arr1[50] = "#####################";
    char arr2[] = "hello world";
    //printf("%s\n", strcpy(arr1, arr2));
    printf("%s\n", my_strcpy(arr1, arr2));
    return 0;
}

2.3 strcat模拟实现

文档:char * strcat ( char * destination, const char * source );


Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.

源字符串必须以 '\0' 结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

字符串自己给自己追加,要用到strncat,用strcat的话 \0被覆盖了

代码演示:

 
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[30] = "hello";
    char arr2[] = "world";
    strcat(arr1, arr2);
    printf("%s\n", arr1);//helloworld
    return 0;
}


C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(中):https://developer.aliyun.com/article/1513076

目录
相关文章
|
2天前
|
C语言
C语言----字符函数和字符串函数(4)
C语言----字符函数和字符串函数
|
2天前
|
算法 C语言
C语言----字符函数和字符串函数(3)
C语言----字符函数和字符串函数
11 0
|
2天前
|
C语言
C语言----字符函数和字符串函数(2)
C语言----字符函数和字符串函数
|
2天前
|
C语言
C语言---函数---请输入乘法口诀表的行,来打印几几乘法表
C语言---函数---请输入乘法口诀表的行,来打印几几乘法表
|
2天前
|
C语言
C语言--函数递归与迭代
C语言--函数递归与迭代
|
4天前
|
算法 Java C语言
Java中的算法与C语言中的函数
Java中的算法与C语言中的函数
9 2
|
9天前
|
安全 C语言
【C语言基础】:内存操作函数
【C语言基础】:内存操作函数
|
2天前
|
C语言 C++
C语言----C语言内存函数
C语言----C语言内存函数
|
2天前
|
C语言
C语言----字符函数和字符串函数(1)
C语言----字符函数和字符串函数
|
2天前
|
C语言
C语言---函数递归
C语言---函数递归