關於字符串庫函數的實現

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

//strcpy(p, p1) 複製字符串 
///strncpy(p, p1, n) 複製指定長度字符串
char *My_strcpy1(char *des, const char *src, int len1, int len2)
{
    char *p = des;
    assert((len1 >= len2)&&(*src != NULL));
    while(*src != '\0')
    {
        *des = *src;
        des++;
        src++;
    }//while(*des++ = *src++)
    *des = '\0';
    return p;
}
//拷貝
char *My_strcpy2(char *des, const char *src, int len1, int len2)
{
    assert((len1 >= len2)&&(*src != NULL));
    int i;
    for(i = 0; src[i] != '\0'; i++)
    {
        des[i] = src[i];
    }
    des[i] = '\0';
    return des;
}
//拷貝
char *My_strncpy(char *des, const char *src, int len1, int len2, int n)
{
    assert((len1 >= len2)&&(*src != NULL));
    int i;
    for(i = 0; src[i] != '\0' && i < n; i++)
    {
        des[i] = src[i];
    }
    return des;
}
//拷貝

//strlen(p) 取字符串長度
int My_strlen(const char *src)
{
    int temp = 0;
    while(*src != '\0')
    {
        temp++;
        src++;
    }
    return temp;
}
//長度

//strcmp(p, p1) 比較字符串 
//strncmp(p, p1, n) 比較指定長度字符串
int My_strcmp(const char *str1, const char *str2)
{
    assert((*str1 != NULL)&&(*str2 != NULL));
    int temp;
    while((temp = *str1 - *str2) == 0)
    {
        str1++;
        str2++;
    }
    return temp;
}
//比較
int My_strncmp(const char *str1, const char *str2, int n)
{
    assert((*str1 != NULL)&&(*str2 != NULL));
    int i;
    int temp;
    for(i = 0; str2[i] != '\0' && i < n; i++)
    {
        while((temp = *str1 - *str2) == 0)
        {
            str1++;
            str2++;
        }
    }
    return temp;
}
//比較

//strcat(p, p1) 附加字符串 
//strncat(p, p1, n) 附加指定長度字符串
char *My_strcat(char *des, const char *src)
{
    assert(src != NULL);
    char *p = des;
    while(*des != '\0')
    {
        des++;
    }
    while(*src != '\0')
    {
        *des++ = *src++;
    }
    *des = '\0';
    return p;
}
//字符串連接
char *My_strncat(char *des, const char *src, int n)
{
    assert(src != NULL);
    char *p = des;
    while(*des != '\0')
    {
        des++;
    }
    for(int i = 0; *src != '\0' && i < n; i++)
    {
        *des++ = *src++;
    }
    *des = '\0';
    return p;
}
//字符串連接

void Func(char *str1)
{
    assert(*str1 != NULL);
    int flag = 0;
    int word = 0;
    int count = 0;
    while(*str1 != '\0')
    {
        if(*str1 == ' ')
        {
            flag = 0;
        }
        if(isalpha(*str1))
        {
            count++;
            if(*str1 != ' '&& flag == 0)
            {
                flag = 1;
                word++;
            }
        }
        str1++;
    }
    printf("字符個數  %d\n", count);
    printf("單詞量  %d\n", word);
}
//字符個數、單詞量

char *My_itoa(int num, char *str)
{
    char *p = str;
    int i = 0;
    int j;
    char temp;
    int flag = 1;
    while(num != 0)
    {
        if(num < 0)
        {
            num = -num;
            flag = -1;
        }
        str[i] = num % 10 + '0';
        num = num / 10;
        i++;
    }
    if(flag < 0)
    {
        str[i++] = '-';
    }
    str[i] = '\0';
    i--;
    for(j = 0; j < i; j++, i--)
    {
        temp = str[j];
        str[j] = str[i];
        str[i] = temp;
    }
    return p;
}
//整數轉字符
int My_atoi(const char *str)
{
    assert(*str != NULL);
    int flag = 1;
    //int i;
    int num = 0;
    while(isspace(*str) == ' ')
    {
        str++;
    }
    if(*str == '-')
    {
        flag = -1;
        str++;
    }
    else if(*str == '+')
    {
        str++;
    }
    while(*str != '\0' && isdigit(*str))
    {
        num = num * 10 + *str - '0';
        str++;
    }
    return num*flag;
}
//字符轉整數

int main()
{
    char str[30];
    char *str4 = "1a2b3";
    char *str5 = "-123";
    char str1[30] = "ab cd ef fe  ";
    char *str3 = "   ab cd ef";
    char *str2 = "tulun";
    int len1 = sizeof(str1)/sizeof(str1[0]);
    int len2 = sizeof(str2)/sizeof(str2[0]);
    printf("My_strcpy1  %s\n", My_strcpy1(str1, str2, len1, len2));
    printf("My_strcpy2  %s\n", My_strcpy2(str1, str2, len1, len2));
    printf("My_strncpy  %s\n", My_strncpy(str1, str2, len1, len2, 3));
    printf("My_strlen  %d\n", My_strlen(str1));
    printf("My_strcmp %d\n", My_strcmp(str3, str2));
    printf("My_strncmp  %d\n", My_strncmp(str3, str2, 3));
    printf("My_strcat  %s\n", My_strcat(str1, str2));
    printf("My_strncat  %s\n", My_strncat(str1, str2, 2));
    printf("My_itoa  %s\n", My_itoa(-123, str));
    printf("My_atoi  %d\n", My_atoi(str4));
    printf("My_atoi  %d\n", My_atoi(str5));
    Func(str1);
    Func(str3);
    getchar();
    return 0;
}

1、返回值的作用:鏈式表達式

int len = strlen(strcpy(str1, str2));

2、關於const:固定離其最近的
const在 * 之前表示內容不變;
const在 * 之後表示指針不變;

const char *str1 = char const *str2 = "abc";//常量字符串,不能修改指向內容
char *const str2 = "def";//常量指針
str1 = str2;

3、assert函數:斷言,準確快速地找到錯誤(debug條件下)

#include <assert.h>
void assert( int expression );

assert的作用是現計算表達式 expression ,如果其值爲假(即爲0),那麼它先向stderr打印一條出錯信息,然後通過調用 abort 來終止程序運行。

4、
c語言中的isalpha,isdigit,islower,isupper等一系列函數

5、*(str + 1) 與 str[1] 存取效率:
(1)*(str + 1)
str本身地址—>取出str存放數據地址—>訪問數據
(2)str[1]
str的地址—>str + 1

6、strtok函數

char *strtok(char s[], const char *delim);

1)功能:分解字符串爲一組字符串。s爲要分解的字符串,delim爲分隔符字符串,所有delim中包含的字符都會被濾掉,並將被濾掉的地方設爲一處分割的節點。

2)掃描字符串s,找到delim(假設指定” “)—–>將s中找到的” “變成0,
(1)第一次調用:

strtok(str, " "); //先從原串首字符開始掃描(strtok通過自定義分隔符分隔字符串),

(2)第二次及多次調用:

strtok(NULL, " "); //再從判斷後指針指向的位置開始判斷

3)返回值:
每次調用成功則返回指向被分割出片段的指針;
當查找不到delim中的字符時,返回NULL。

7、越界問題:
(1)不檢驗’\0’是否屬於其拷貝或計算的字符串對象
strcpy()函數是針對C風格字符串進行拷貝的,即遇’\0’而停止拷貝;
strlen()函數只拷貝字符串的實際顯示的字符長度,而不包括’\0’字符
(2)不考慮內存重疊問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章