20160222.CCPP體系詳解(0032天)

尹成發表於2016-03-20

程式片段(01):寬字元.c+字串與記憶體四區.c
內容概要:寬窄字元

///寬字元.c
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

//01.寬字元的應用:
//  1.寬字元用於國際化:
//      Unicode編碼情況之下,需要啟用寬字元程式設計
//  2.中文的高階處理:
//      必須依賴於寬字元
//  3.寬窄字元的唯一不同特點:
//      儲存資料的盒子尺寸不一致(寬字元采用雙位元組儲存,窄字元采用單位元組儲存)
//      注:其它特性和窄字元一致
//  4.寬字元情況之下:
//      所有單個寬字元都佔據兩個位元組的記憶體空間
//  5.設定本地化的目的:
//      啟用本地字符集,以實現基於本地化的國際化
//  注:
//      1.L'X'-'X'和L"ABC"-"ABC"兩種儲存方式儲存的資料實質都是一樣的,不一樣的
//          只是儲存該資料的盒子尺寸不一樣
//      2.寬窄字元的使用注意事項:
//          寬字元:
//              如果沒有設定本地化的情況之下,也就只能處理ASCII碼錶包含字元
//              只有在設定了正確的本地化的情況之下,才能正確的處理本地語言   
//          窄字元:
//              無論是否設定本地化,都只能處理ASCII碼錶當中所定義的字元
//              也就是說只有寬字元才存在設定本地化的不同點
//      3.寬窄字元的結尾識別符號:
//          寬字元:L'\0'
//          窄字元:'\0
//          注:所有位於程式碼區常量池的字串預設攜帶結尾識別符號
//02.採用窄字元儲存中文的特點分析:
//  1.所有ASCII碼錶所包含的字元都只佔用一個位元組
//  2.所有中文字元將會包含兩個位元組
//  注:窄字元儲存原理
int main01(void)
{
    char * p1 = "我";
    char * p2 = "我的";//所有位於程式碼區常量池的字串結尾預設自帶'\0'orL'\0'
    printf("%d, %d \n", sizeof("我"), sizeof("我的"));
    printf("%s \n", p1);//窄字元情況下:分ASCII碼錶字元和非ASCII碼錶字元

    system("pause");
}

//03.非ASCII碼錶的其他字元如果按照字元陣列進行儲存:
//  就需要按照其他字元所佔據的位元組個數進行連續字元的列印,這樣才能正確
//  的還原字元陣列當中所儲存的字串內容
int main02(void)
{
    char str[10] = "我";//非ASCII碼錶內容按照窄字元陣列儲存,需要按照連續的單位元組個數進行字元解析
    printf("%c%c \n", *(str + 0), *(str + 1));//方能正確的顯示非ASCII碼錶字串

    system("pause");
}

//04.寬窄字元使用注意事項:
//  1.嚴格區分寬窄字元
//  2.嚴格區分單字元還是字串:
//      單字元:就是單個字元
//      字串:含有結束標識
//  3.嚴格區分佔用位元組和使用位元組:
//注:認真區分寬窄字元的儲存原理!
int main03(void)
{
    wchar_t wchr1 = L'我';
    wchar_t wstr[10] = L"我的C";
    printf("%d \n", sizeof(wchr1));//2
    printf("%d \n", sizeof(wstr));//20
    printf("%d \n", sizeof(L"我的C1"));//寬字元:無論是何種字元,都按照兩個位元組進行儲存

    system("pause");
}

//05.寬窄字元都遵守記憶體四區理論
int main04(void)
{
    wchar_t * p = L"我的C";//寬窄字元都遵從記憶體四區理論
    *p = L'X';

    system("pause");
}

//06.無論是寬字元的字元還是字串:
//  都必須要求新增上寬字元字首標識L
//      寬字元(單字元):L''
//      寬字元(字串):L""
//07.寬字元細節問題:
//  1.寬字元(單字元):
//      外部標識:L''
//      格式控制:%c
//  2.寬字元(字串)
//      外部標識:L""
//      格式控制:%ls
//注:寬字元最好同時使用(本地化)+(寬字元標識)+(寬字元函式)+(寬字元格式控制)
//  這樣寬字元才能保證完全正確的顯示
int main05(void)
{
    setlocale(LC_ALL, "zh-CN");
    wchar_t * pWChr = L"12345abcdef我的王";
    //printf("%s \n", pWChr);//型別不匹配
    wprintf(L"wprintf = %ls \n", pWChr);

    system("pause");
}

int main06(void)
{
    setlocale(LC_ALL, L"zh-CN");
    wchar_t wchr = L'我';
    putwchar(wchr);

    system("pause");
}
///字串與記憶體四區.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char str[100] = "12345";

//01.除了程式碼區當中的內容不可進行修改,其他地兒幾乎都可以:
//      程式碼區常量池:直接獲取
//      程式碼區符號表:先讀取,再生成,最後才能使用
int main07(void)
{
    char * pStr1 = "ABCDEF";//程式碼區
    char str[100] = "1234567";//棧記憶體
    char * pStr2 = (char *)malloc(100);//堆記憶體
    strcpy(pStr2, "ABCDEF");
    //*pStr1 = 'X';
    *pStr2 = 'X';
    *str = 'X';
    char * pChr = str;
    printf("%s, %s, %s \n", pStr1, str, pStr2);

    system("pause");
}

int main08(void)
{
    char * pStr1 = "ABCDEF";
    char * pStr2 = "ABCDEF";//程式碼區常量池當中的相同常量字串只有一份兒(地址相同)
    char str1[10] = "ABCDEF";
    char str2[10] = "ABCDEF";
    char * pM1 = (char *)malloc(10);    
    char * pM2 = (char *)malloc(10);
    strcpy(pM1, "ABCDEF");
    strcpy(pM2, "ABCDEF");
    printf("%d, %d, %d \n", pStr1 == pStr2, str1 == str2, pM1 == pM2);

    system("pause");
}

char strX[100] = "ABCDEF";
char * getStr()
{
    char str[100] = "ABCDEF";//返回棧記憶體不可以
    char * pStr = "ABCDEF";//程式碼區地址
    char * pStrX = strX;//靜態區地址
    return pStrX;
}

//02.函式的返回值所能返回的指標特點:
//  1.絕對不能返回指向棧記憶體的指標
//  2.返回指向棧記憶體的指標屬於迷途指標:
//      迷途指標:指標所指向的記憶體塊兒已經被回收了
int main09(void)
{
    char * pStr;
    pStr = getStr();
    printf("\n\n\n");
    free(pStr);//迷途指標
    pStr == NULL;//指標為空
    printf("%s \n", pStr);

    system("pause");
}

程式片段(02):MyString.h+MyString.c+main.c
內容概要:字串庫封裝

///MyString.h
#pragma once
#include <stdlib.h>

typedef struct 
{
    char * pAStr;//首地址
    int memLen;//實際長
} MyAString;

typedef struct 
{
    wchar_t * pWStr;
    int memLen;
} MyWString;

//指定初始
void initMyAStrWithAStr(MyAString * pMyAStr, char const * pAStr);
void initMyWStrWithWStr(MyWString * pMyWStr, wchar_t const * pWStr);

//顯示字串
void showMyAStr(MyAString * pMyAStr);
void showMyWStr(MyWString * pMyWStr);

//字串長度
int myAStrLen(MyAString * pMyAStr);
int myWStrLen(MyWString * pMyWstr);

//字串拷貝
MyAString * myAStrCpy(MyAString * pMyAStr, char const * pAStr);
MyWString * myWStrCpy(MyWString * pMyWStr, wchar_t const * pWStr);

//遞迴拷貝
MyAString * myAStrCopy(MyAString * pMyAStr, char const * pAStr, int i);
MyWString * myWStrCopy(MyWString * pMyWStr, wchar_t const * pWStr, int i);

//尾部追加
void myAStrAddAStr(MyAString * pMyAStr, char const * pAStr);
void myWStrAddWStr(MyWString * pMyWStr, wchar_t const * pWStr);

//字串查詢
char * myAStrAStr(MyAString * pMyAStr, char * pAStr);
wchar_t * myWStrWStr(MyWString * pMyWStr, wchar_t * pWStr);

//隨機前插
void myAStrPrevInsertAStr(MyAString * pMyAStr, char * pAStr, char * pInsertAStr);
void myWStrPrevInsertWStr(MyWString * pMyWstr, wchar_t * pWStr, wchar_t * pInsertWStr);

//隨機後插
void myAStrNextInsertAStr(MyAString * pMyAStr, char * pAStr, char * pInsertAStr);
void myWStrNextInsertWStr(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pInsertWStr );

//刪除單個
void myAStrDelFirstAStr(MyAString * pMyAStr, char * pAStr);
void myWStrDelFirstWStr(MyWString * pMyWStr, wchar_t * pWStr);

//刪除多個
void myAStrDelAllAStr(MyAString * pMyAStr, char * pAStr);
void myWStrDelAllWStr(MyWString * pMyWStr, wchar_t * pWStr);
void myAStrDelAllAStrByRec(MyAString * pMyAStr, char * pAStr);
void myWStrDelAllWStrByRec(MyWString * pMyWStr, wchar_t * pWStr);


//隨機替換(低效率)
void myAStrRepFirstAStrLow(MyAString * pMyAStr, char * pAStr, char * pRepAStr);
void myWStrRepFirstWStrLow(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr);
void myAStrRepAllAStrLow(MyAString * pMyAStr, char * pAStr, char * pRepAStr);
void myWStrRepAllWStrLow(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepStr);

//隨機替換(高效率)
void myAStrRepFirstAStrHigh(MyAString * pMyAStr, char * pAStr, char * pRepAStr);
void myWStrRepFirstWStrHigh(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr);
void myAStrRepAllAStrHigh(MyAString * pMyAStr, char * pAStr, char * pRepAStr);
void myWStrRepAllWStrHigh(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr);

//擴充功能:
//字串壓縮:
//  1.時間優先or空間優先
//  2.單字元壓縮和字串壓縮
///MyString.c
#define _CRT_SECURE_NO_WARNINGS
#include "MyString.h"
#include <string.h>
#include <stdio.h> 

void showMyAStr(MyAString * pMyAStr)
{
    if (NULL == pMyAStr->pAStr)
        return;
    printf("%s \n", pMyAStr->pAStr);
}

void showMyWStr(MyWString * pMyWStr)
{
    if (NULL == pMyWStr->pWStr)
        return;
    wprintf(L"%ls \n", pMyWStr->pWStr);
}

int myAStrLen(MyAString * pMyAStr)
{
    if (NULL == pMyAStr)
        return 0;
    int i = 0;
    while (*pMyAStr->pAStr++)
    {
        ++i;
    }

    return i;
}

int myWStrLen(MyWString * pMyWStr)
{
    if (NULL == pMyWStr)
        return 0;
    int i = 0;
    while (*pMyWStr->pWStr++)
    {
        ++i;
    }

    return i;
}

MyAString * myAStrCpy(MyAString * pMyAStr, char const * pAStr)
{
    if (NULL == pMyAStr || NULL == pAStr)
        return NULL;
    //pAStrLen = strlen(pAStr);
    //for (int i = 0; i < pAStrlen + 1; ++i)
    //{
    //  *(pMyAStr->pAStr + i) = *(pAStr + i);
    //}
    char * pCopy = pMyAStr->pAStr;
    while (*pCopy++ = *pAStr++);
    return pMyAStr;
}

MyWString * myWStrCpy(MyWString * pMyWStr, wchar_t const * pWStr)
{
    if (NULL == pMyWStr || NULL == pWStr)
        return NULL;
    //int pWStrLen = wcslen(pWStr);
    //for (int i = 0; i < pWStrLen + 1; ++i)
    //{
    //  *(pMyWStr->pWStr + i) = *(pWStr + i);
    //}
    wchar_t * pCopy = pMyWStr->pWStr;
    while (*pCopy++ = *pWStr++);
    return pMyWStr;
}

MyAString * myAStrCopy(MyAString * pMyAStr, char const * pAStr, int i)
{
    if (!(*(pMyAStr->pAStr + i) = *(pAStr + i++)))
        return pMyAStr;
    myAStrCopy(pMyAStr, pAStr, i);
}

MyWString * myWStrCopy(MyWString * pMyWStr, wchar_t const * pWStr, int i)
{
    //static char * pTemp = pWStr;//靜態區域性變數不能使用變數進行初始化
    if (!(*(pMyWStr->pWStr + i) = *(pWStr + i++)))
        return pMyWStr;
    myWStrCopy(pMyWStr, pWStr, i);
}

void    initMyAStrWithAStr(MyAString * pMyAStr, char const * pAStr)
{
    if (NULL == pMyAStr || NULL == pAStr)
        abort();
    int myStrLen = strlen(pAStr) + 1;
    pMyAStr->pAStr = (char *)malloc(myStrLen * sizeof(char));
    //myAStrCpy(pMyAStr, pAStr);
    myAStrCopy(pMyAStr, pAStr, 0);
    pMyAStr->memLen = myStrLen + 1;
}

void initMyWStrWithWStr(MyWString * pMyWStr, wchar_t const * pWStr)
{
    if (NULL == pMyWStr || NULL == pWStr)
        abort();
    int myWStrLen = wcslen(pWStr) + 1;
    pMyWStr->pWStr = (wchar_t *)malloc(myWStrLen * sizeof(wchar_t));
    //myWStrCpy(pMyWStr, pWStr);
    myWStrCopy(pMyWStr, pWStr, 0);
    pMyWStr->memLen = myWStrLen;
}

void myAStrAddAStr(MyAString * pMyAStr, char const * pAStr)
{
    if (NULL == pMyAStr || NULL == pAStr)
        abort();
    if (NULL == pMyAStr)
    {
        initMyAStrWithAStr(pMyAStr, pAStr);
    }
    else
    {
        int myAStrLen = strlen(pMyAStr->pAStr);
        int addAStrLen = strlen(pAStr);
        int allAStrLen = myAStrLen + addAStrLen + 1;
        if (pMyAStr->memLen < allAStrLen)
        {
            pMyAStr->pAStr = (char *)realloc(pMyAStr->pAStr, allAStrLen * sizeof(char));
            pMyAStr->memLen = allAStrLen;
        }
        strcat(pMyAStr->pAStr, pAStr);
    }
}

void myWStrAddWStr(MyWString * pMyWStr, wchar_t const * pWStr)
{
    if (NULL == pMyWStr || NULL == pWStr)
        abort();
    if (NULL == pMyWStr->pWStr)
    {
        initMyWStrWithWStr(pMyWStr, pWStr);
    }
    else
    {
        int myWStrLen = wcslen(pMyWStr->pWStr);
        int addWStrLen = wcslen(pWStr);
        int allWStrLen = myWStrLen + addWStrLen + 1;
        if (pMyWStr->memLen < allWStrLen)
        {
            pMyWStr->pWStr = (wchar_t *)realloc(pMyWStr->pWStr, allWStrLen * sizeof(wchar_t));
            pMyWStr->memLen = allWStrLen;
        }
        wcscat(pMyWStr->pWStr, pWStr);
    }
}

char * myAStrAStr(MyAString * pMyAStr, char * pAStr)
{
    if (NULL == pMyAStr || NULL == pMyAStr->pAStr || NULL == pAStr)
        return NULL;
    int pMyAStrLen = strlen(pMyAStr->pAStr);
    int pAStrLen = strlen(pAStr);
    int diffAStrLen = pMyAStrLen - pAStrLen;
    for (int i = 0; i <= diffAStrLen; ++i)
    {
        int find = 1;
        for (int j = 0; j < pAStrLen; ++j)
        {
            if (*(pMyAStr->pAStr + i + j) != *(pAStr + j))
            {
                find = 0;
                break;
            }
        }
        if (find)
        {
            return pMyAStr->pAStr + i;
        }
    }
    return NULL;
}

wchar_t * myWStrWStr(MyWString * pMyWStr, wchar_t  * pWStr)
{
    if (NULL == pMyWStr || NULL == pMyWStr->pWStr || NULL == pWStr)
        return NULL;
    wchar_t * pCopy = pMyWStr->pWStr;
    while (*pCopy)
    {
        int find = 1;
        wchar_t *pTmp = pCopy;
        wchar_t *pTemp = pWStr;
        while (*pTemp)
        {
            if ('\0' == *pTmp || *pTmp != *pTemp)
            {
                find = 0;
                break;
            }
            ++pTmp;
            ++pTemp;
        }
        if (find)
        {
            return pCopy;
        }
        ++pCopy;
    }
    return NULL;
}

void myAStrPrevInsertAStr(MyAString * pMyAStr, char * pAStr, char * pInsertAStr)
{
    if (NULL == pMyAStr || NULL == pMyAStr->pAStr || NULL == pInsertAStr)
        return;
    char * pFind = myAStrAStr(pMyAStr, pAStr);
    if (NULL == pFind)
        return;
    int myAStrLen = strlen(pMyAStr->pAStr);
    int insertAStrLen = strlen(pInsertAStr);
    int totalAStrLen = myAStrLen + insertAStrLen + 1;
    int relativeLen = pFind - pMyAStr->pAStr;
    if (pMyAStr->memLen < totalAStrLen)
    {
        pMyAStr->pAStr = (char *)realloc(pMyAStr->pAStr, totalAStrLen * sizeof(char));
        pMyAStr->memLen = totalAStrLen;
    }
    for (int i = myAStrLen; i >= relativeLen; --i)
    {
        pMyAStr->pAStr[i + insertAStrLen] = pMyAStr->pAStr[i];
    }
    for (int i = relativeLen, j = 0; i < relativeLen + insertAStrLen; ++i)
    {
        pMyAStr->pAStr[i] = pInsertAStr[j++];
    }
}

void myWStrPrevInsertWStr(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pInsertWStr)
{
    if (NULL == pMyWStr->pWStr || NULL == pInsertWStr)
        return;
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL == pFindWStr)
        return;
    int myWStrLen = wcslen(pMyWStr->pWStr);
    int insertWStrLen = wcslen(pInsertWStr);
    int totalWStrLen = myWStrLen + insertWStrLen + 1;
    if (pMyWStr->memLen < totalWStrLen)
    {
        pMyWStr->pWStr = (wchar_t *)realloc(pMyWStr->pWStr, totalWStrLen * sizeof(wchar_t));
        pMyWStr->memLen = totalWStrLen;
    }
    pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    for (wchar_t * p = pMyWStr->pWStr + myWStrLen; p >= pFindWStr; --p)
    {
        *(p + insertWStrLen) = *p;
    }
    while (*pInsertWStr)
    {
        *pFindWStr++ = *pInsertWStr++;
    }
}

void myAStrNextInsertAStr(MyAString * pMyAStr, char * pAStr, char * pInsertAStr)
{
    if (NULL == pMyAStr->pAStr || NULL == pInsertAStr)
        return;
    char * pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    if (NULL == pFindAStr)
        return;
    int myAStrLen = strlen(pMyAStr->pAStr);
    int findAStrLen = strlen(pFindAStr);
    int relAStrLen = myAStrLen - findAStrLen;
    int insertAStrLen = strlen(pInsertAStr);
    int totalAStrLen = myAStrLen + insertAStrLen + 1;
    if (pMyAStr->memLen < totalAStrLen)
    {
        pMyAStr->pAStr = (char *)realloc(pMyAStr->pAStr, totalAStrLen * sizeof(char));
        pMyAStr->memLen = totalAStrLen;
    }
    for (int i = myAStrLen; i >= relAStrLen + strlen(pAStr); --i)
    {
        *(pMyAStr->pAStr + i + insertAStrLen) = *(pMyAStr->pAStr + i);
    }
    for (int i = 0; i < insertAStrLen; ++i)
    {
        *(pMyAStr->pAStr + relAStrLen + strlen(pAStr) + i) = *(pInsertAStr + i);
    }
}

void myWStrNextInsertWStr(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pInsertWStr)
{
    if (NULL == pMyWStr->pWStr || NULL == pInsertWStr)
        return;
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL == pFindWStr)
        return;
    int myWStrLen = wcslen(pMyWStr->pWStr);
    int insertWStrLen = wcslen(pInsertWStr);
    int totalWStrLen = myWStrLen + insertWStrLen + 1;
    if (pMyWStr->memLen < totalWStrLen)
    {
        pMyWStr->pWStr = (wchar_t *)realloc(pMyWStr->pWStr, totalWStrLen * sizeof(wchar_t));
        pMyWStr->memLen = totalWStrLen;
    }
    pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    for (wchar_t * p = pMyWStr->pWStr + myWStrLen; p >= pFindWStr + wcslen(pWStr); --p)
    {
        *(p + insertWStrLen) = *p;
    }
    while (*pInsertWStr)
    {
        *(pFindWStr + wcslen(pWStr)) = *pInsertWStr++;
        ++pFindWStr;
    }
}

void myAStrDelFirstAStr(MyAString * pMyAStr, char * pAStr)
{
    char * pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    if (NULL == pFindAStr)
        return;
    int delAStrLen = strlen(pAStr);
    char * pRepAStr = pFindAStr + delAStrLen;
    //while ('\0' != *pFindAStr)
    //while (0 != pFindAStr)
    //while (*pFindAStr)
    //{
    //  *pFindAStr = *pRepAStr;
    //  ++pRepAStr;
    //  ++pFindAStr;
    //}
    //while (*pFindAStr++ = *pRepAStr++);
    //while (*pFindAStr = *(pFindAStr + delAStrLen))
    //{
    //  ++pFindAStr;
    //}
    while (*pFindAStr++ = *(pFindAStr + delAStrLen));
}

void myWStrDelFirstWStr(MyWString * pMyWStr, wchar_t * pWStr)
{
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL == pFindWStr)
        return;
    int delWStrLen = wcslen(pWStr);
    wchar_t *   pRepWStr = pFindWStr + delWStrLen;
    //while ('\0' != *pFindWStr);
    //while (0 != *pFindWStr);
    //while (*pFindWStr)
    //{
    //  *pFindWStr = *pRepWStr;
    //  ++pRepWStr;
    //  ++pFindWStr;
    //}
    //while (*pFindWStr++ = *pRepWStr++);
    //while (*pFindWStr = *(pFindWStr + delWStrLen))
    //{
    //  ++pFindWStr;
    //}
    while (*pFindWStr++ = *(pFindWStr + delWStrLen));
}

void myAStrDelAllAStr(MyAString * pMyAStr, char * pAStr)
{
    char * pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    while (NULL != pFindAStr)
    {
        myAStrDelFirstAStr(pMyAStr, pAStr);
        pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    }
}

void myWStrDelAllWStr(MyWString * pMyWStr, wchar_t * pWStr)
{
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL != pFindWStr)
    {
        do
        {
            myWStrDelFirstWStr(pMyWStr, pWStr);
            pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
        } while (NULL != pFindWStr);
    }
}

void myAStrDelAllAStrByRec(MyAString * pMyAStr, char * pAStr)
{
    if (NULL == strstr(pMyAStr->pAStr, pAStr))
        return;
    myAStrDelFirstAStr(pMyAStr, pAStr);
    myAStrDelAllAStr(pMyAStr, pAStr);
}

void myWStrDelAllWStrByRec(MyWString * pMyWStr, wchar_t * pWStr)
{
    if (NULL == wcsstr(pMyWStr->pWStr, pWStr))
        return;
    myWStrDelFirstWStr(pMyWStr, pWStr);
    myWStrDelAllWStrByRec(pMyWStr, pWStr);
}

void myAStrRepFirstAStrLow(MyAString * pMyAStr, char * pAStr, char * pRepAStr)
{
    char * pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    if (NULL == pFindAStr)
        return;
    myAStrPrevInsertAStr(pMyAStr, pAStr, pRepAStr);
    myAStrDelFirstAStr(pMyAStr, pAStr);
}

void myWStrRepFirstWStrLow(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr)
{
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL == pFindWStr)
        return;
    myWStrPrevInsertWStr(pMyWStr, pWStr, pRepWStr);
    myWStrDelFirstWStr(pMyWStr, pWStr);
}

void myAStrRepAllAStrLow(MyAString * pMyAStr, char * pAStr, char * pRepAStr)
{
    if (NULL == strstr(pMyAStr->pAStr, pAStr))
        return;
    myAStrRepFirstAStrLow(pMyAStr, pAStr, pRepAStr);
    myAStrRepAllAStrLow(pMyAStr, pAStr, pRepAStr);
}

void myWStrRepAllWStrLow(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr)
{
    if (NULL == wcsstr(pMyWStr->pWStr, pWStr))
        return;
    myWStrRepFirstWStrLow(pMyWStr, pWStr, pRepWStr);
    myWStrRepAllWStrLow(pMyWStr, pWStr, pRepWStr);
}

void myAStrRepFirstAStrHigh(MyAString * pMyAStr, char * pAStr, char * pRepAStr)
{
    char * pFindAStr = strstr(pMyAStr->pAStr, pAStr);
    if (NULL == pFindAStr)
        return;
    int pAStrLen = strlen(pAStr);
    int pRepAStrLen = strlen(pRepAStr);
    int allAStrLen = strlen(pMyAStr->pAStr) + 1 + (pRepAStrLen - pAStrLen);
    if (pAStrLen < pRepAStrLen)
    {
        if (allAStrLen < pMyAStr->memLen)
        {
            pMyAStr->pAStr = (char *)realloc(pMyAStr->pAStr, allAStrLen*sizeof(char));
            pMyAStr->memLen = allAStrLen;
        }
        pFindAStr = strstr(pMyAStr->pAStr, pAStr);
        int addAStrLen = pRepAStrLen - pAStrLen;
        for (char * p = pMyAStr->pAStr + strlen(pMyAStr->pAStr); p >= pFindAStr + pAStrLen; --p)
        {
            *(p + addAStrLen) = *p;
        }
        while (*pRepAStr)
        {
            *pFindAStr++ = *pRepAStr;
            ++pRepAStr;
        }
    }
    else if (pAStrLen == pRepAStrLen)
    {
        while (*pRepAStr)
        {
            *pFindAStr++ = *pRepAStr++;
        }
    }
    else
    {
        int subAStrLen = pRepAStrLen - pAStrLen;
        while (*pRepAStr)
        {
            *pFindAStr++ = *pRepAStr++;
        }
        char * pTemp = pFindAStr + pAStrLen;
        while (*pTemp++ = *(pTemp + subAStrLen));
    }
}

void myAStrRepAllAStrHigh(MyAString * pMyAStr, char * pAStr, char * pRepAStr)
{
    if (NULL == strstr(pMyAStr->pAStr, pAStr))
        return;
    myAStrRepFirstAStrHigh(pMyAStr, pAStr, pRepAStr);
    myAStrRepAllAStrHigh(pMyAStr, pAStr, pRepAStr);
}

void myWStrRepFirstWStrHigh(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr)
{
    wchar_t * pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
    if (NULL == pFindWStr)
        return;
    int pWStrLen = wcslen(pWStr);
    int pRepWStrLen = wcslen(pRepWStr);
    if (pWStrLen < pRepWStrLen)
    {
        int totalWStrLen = wcslen(pMyWStr->pWStr) + (pRepWStrLen - pWStrLen) + 1;
        if (pMyWStr->memLen < totalWStrLen)
        {
            pMyWStr->pWStr = (wchar_t *)realloc(pMyWStr->pWStr, totalWStrLen * sizeof(wchar_t));
            pMyWStr->memLen = totalWStrLen;
        }
        pFindWStr = wcsstr(pMyWStr->pWStr, pWStr);
        int myWStrLen = wcslen(pMyWStr->pWStr);
        int moveWStrLen = pRepWStrLen - pWStrLen;
        for (wchar_t * p = pMyWStr->pWStr + myWStrLen; p >= pFindWStr + pWStrLen; --p)
        {
            *(p + moveWStrLen) = *p;
        }
        while (*pRepWStr)
        {
            *pFindWStr++ = *pRepWStr++;
        }
    }
    else if (pWStrLen == pRepWStr)
    {
        while (*pRepWStr)
        {
            *pFindWStr++ = *pRepWStr++;
        }
    }
    else
    {
        int moveWStrLen = pWStrLen - pRepWStrLen;
        wchar_t * p = pFindWStr + pWStrLen - moveWStrLen;
        while (*p++ = *(p + moveWStrLen));
        while (*pRepWStr)
        {
            *pFindWStr++ = *pRepWStr++;
        }
    }
}

void myWStrRepAllWStrHigh(MyWString * pMyWStr, wchar_t * pWStr, wchar_t * pRepWStr)
{
    if (NULL == wcsstr(pMyWStr->pWStr, pWStr))
        return;
    myWStrRepFirstWStrHigh(pMyWStr, pWStr, pRepWStr);
    myWStrRepAllWStrHigh(pMyWStr, pWStr, pRepWStr);
}
///main.c
#define _CRT_SECURE_NO_WARNINGS
#include "MyString.h"
#include <locale.h>
#include <stdio.h>

int main(void)
{
    setlocale(LC_ALL, "zh-CN");
    MyAString myAString;
    MyWString myWString;
    initMyAStrWithAStr(&myAString, "ABC123321CBA123");
    initMyWStrWithWStr(&myWString, L"ABC123321CBA123");
    myAStrAddAStr(&myAString,"HaHaHa嘻嘻嘻");
    myWStrAddWStr(&myWString, L"XiXiXi哈哈哈");
    //myAStrPrevInsertAStr(&myAString, "123", "JKL");
    //myAStrNextInsertAStr(&myAString, "123", "JKL");
    //myWStrPrevInsertWStr(&myWString, L"123", L"JKL");
    //myWStrNextInsertWStr(&myWString, L"123", L"JKL"); 
    //myAStrDelFirstAStr(&myAString, "ABC");
    //myWStrDelFirstWStr(&myWString, L"ABC");
    //myAStrDelAllAStr(&myAString, "123");
    //myWStrDelAllWStr(&myWString, L"123");
    //myAStrDelAllAStrByRec(&myAString, "123");
    //myWStrDelAllWStrByRec(&myWString, L"123");
    //myAStrRepFirstAStrLow(&myAString, "123", "JKL");
    //myWStrRepFirstWStrLow(&myWString, L"123", L"JKL");
    //myAStrRepAllAStrLow(&myAString, "123", "JKL");
    //myWStrRepAllWStrLow(&myWString, L"123", L"JKL");
    //myAStrRepFirstAStrHigh(&myAString, "123", "JKL");
    //myAStrRepAllAStrHigh(&myAString, "123", "JKL");
    //myWStrRepFirstWStrHigh(&myWString, L"123", L"JKL");
    //myWStrRepAllWStrHigh(&myWString, L"123", L"JKL");
    showMyAStr(&myAString);
    showMyWStr(&myWString);
    //printf("%s \n", myAStrAStr(&myAString, "123321"));
    //wprintf(L"%ws \n", myWStrWStr(&myWString, L"123321"));

    system("pause");
}

程式片段(03):myarray.h+myarray.c+main.c
內容概要:陣列庫

///myarray.h
#pragma once//1.包含的時候,只包含一次[預編譯的時候]
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define datatype int//2.double ,char-X->int * struct[擴充套件的時候,只能擴充套件基本資料型別]

struct array
{//3.[採用結構體進行陣列模擬]
    datatype *pstart;//陣列首地址
    int length;//長度[陣列]
    int sortstat;//有序或者無序,0無序,1有序
};

struct Res
{//4.[採用結構體模擬字串型別的陣列,由於字串陣列當中的每個元素儲存的是字串地址,所以採用二級指標進行該陣列的模擬動作]
    datatype **ppstat;//建立指標陣列[二級指標(一級指標地址)-->一級指標(變數地址)-->零級指標(資料)]
    int n;
};

//5.[為結構體模擬陣列建立一些針對於該陣列的操作函式]
//[初始化]
void init(struct array *parr);
void initwithdata(struct array *parr, datatype data);
void initwitharray(struct array *parr, datatype *pdata, int datalength);

//[增加]
void addobject(struct array *parr, datatype data);
void addobjects(struct array *parr, datatype *pdata, int datalength);

//[插入]
void insertobject(struct array *parr, datatype data, datatype insertdata);//根據位置插入
void insertobjects(struct array *parr, datatype data, datatype *pdata, int datalength);

//[刪除]
void deletefirstobject(struct array *parr, datatype data);
void deleteallobject(struct array *parr, datatype);

//[修改]
void changefirstobject(struct array *parr, datatype data, datatype newdata);
void changeallobject(struct array *parr, datatype data, datatype newdata);

//[查詢]
datatype * findfirst(struct array *parr, datatype data);//查詢
struct Res findall(struct array *parr, datatype data);//查詢全部

//[顯示]
void show(struct array *parr);

//5.陣列庫擴充套件功能實現
//      (1)排序:選擇,插入,二分插入,冒泡,堆,快速,從左之右
//      (2)插值查詢,二分查詢
//      (3)初始化with可變引數
///myarray.c
#include "myarray.h"

void init(struct array *parr)
{//1.[初始化資料結構] 
    if (parr != NULL)
    {
        parr->pstart = NULL;
        parr->length = 0;
        parr->sortstat = 0;
    }
    else
    {
        printf("init error!");
    }
}

void initwithdata(struct array *parr, datatype data)
{//2[.初始化結構體資料(單個)]
    if (parr != NULL)
    {
        parr->pstart = malloc(sizeof(datatype));
        *(parr->pstart) = data;//初始化
        parr->length = 1;
        parr->sortstat = 0;
    }
    else
    {
        printf("initwithdata error!");
    }
}

void initwitharray(struct array *parr, datatype *pdata, int datalength)
{//3.[初始化結構體資料(多個)]
    if (parr != NULL)
    {
        parr->pstart = malloc(sizeof(datatype)*datalength);
        memcpy(parr->pstart, pdata, sizeof(datatype)*datalength);
        parr->length = datalength;
        parr->sortstat = 0;
    }
    else
    {
        printf("initwitharray error!");
    }
}

void addobject(struct array *parr, datatype data)
{
    if (parr != NULL)
    {//4.該結構體模擬的陣列存在
        if (parr->pstart == NULL || parr->length == 0)
        {//5.該陣列的狀態處於初始化狀態
            initwithdata(parr, data);
        }
        else
        {
            //6.陣列操作說明:5 a[4]-->[5個元素-->最後一個元素為a[4]-->5這個索引為陣列外尾第一個元素]
            parr->pstart = realloc(parr->pstart, (parr->length + 1)*sizeof(datatype));//擴充記憶體
            parr->pstart[parr->length] = data;//插入
            parr->length += 1;//長度自增
        }
    }
    else
    {
        printf("addobject error!");
    }
}

void addobjects(struct array *parr, datatype *pdata, int datalength)
{
    if (parr != NULL)
    {
        if (parr->pstart == NULL || parr->length == 0)
        {
            initwitharray(parr, pdata, datalength);//呼叫初始化
        }
        else
        {
            //7.說明:12345 a[4] &a[5]
            parr->pstart = realloc(parr->pstart, (parr->length + datalength)*sizeof(datatype));//擴充記憶體
            memcpy(parr->pstart + parr->length, pdata, datalength*sizeof(datatype));//8.追加一個陣列的時候,可以指定位置進行追加動作,如果是追加多個資料,建議採用記憶體拷貝機制,提升效率
            parr->length += datalength;//長度自增
        }
    }
    else
    {
        printf("addobjects error!");
    }
}

void insertobject(struct array *parr, datatype data, datatype insertdata)
{
    if (parr != NULL)
    {
        datatype *pfind = findfirst(parr, data);
        if (pfind == NULL)
        {
            printf("can not insertobject error!");
        }
        else
        {
            int curr = pfind - parr->pstart;//9.指標相減確定相對下標,當前資料的相對下標
            //printf("\n curr=%d", curr);//10.同型別的指標相減,自動除以該指標所指向的變數型別長度
            parr->pstart = realloc(parr->pstart, (parr->length + 1)*sizeof(datatype));//擴充記憶體
            for (int i = parr->length - 1; i >= curr; i--)//11.減一的目的是為了從最後一個元素開始進行資料的拖動
            {
                parr->pstart[i + 1] = parr->pstart[i];//往後拖動
            }
            parr->pstart[curr] = insertdata;//插入資料
            parr->length += 1;//長度自增
        }
    }
    else
    {
        printf("insertobject error!");
    }
}

void insertobjects(struct array *parr, datatype data, datatype *pdata, int datalength)
{
    if (parr != NULL)
    {
        datatype *pfind = findfirst(parr, data);
        if (pfind == NULL)
        {
            printf("can not insertobject error!");
        }
        else
        {
            int curr = pfind - parr->pstart;
            parr->pstart = realloc(parr->pstart, (parr->length + datalength)*sizeof(datatype));
            for (int i = parr->length - 1; i >= curr; i--)
            {
                parr->pstart[i + datalength] = parr->pstart[i];
            }
            memcpy(parr->pstart + curr, pdata, datalength*sizeof(datatype));//拷貝陣列
            parr->length += datalength;//修改長度
        }
    }
    else
    {
        printf("insertobjects error!");
    }
}

void deletefirstobject(struct array *parr, datatype data)
{
    if (parr!=NULL)
    {
        datatype *pfind = findfirst(parr, data);
        if (pfind==NULL)
        {
            printf("can not find deleteerror!");
        }
        else
        {
            int curr = pfind - parr->pstart;//指標相減確定下標,當前資料的相對下標
            for (int i = curr; i < parr->length - 1; i++)
            {
                parr->pstart[i] = parr->pstart[i + 1];//刪除,從後向前移動
            }
            parr->length -= 1;//長度自減
            parr->pstart = realloc(parr->pstart, (parr->length)*sizeof(datatype));//壓縮記憶體
        }
    }
    else
    {
        printf("deleteobject error!");
    }
}

void deleteallobject(struct array *parr, datatype data)
{
    if (parr!=NULL)
    {
        for (int *pcurr = findfirst(parr, data); pcurr != NULL; pcurr = findfirst(parr, data))
        {
            deletefirstobject(parr, data);
        }
    }
    else
    {
        printf("deleteobject error!");
    }
}

void changefirstobject(struct array *parr, datatype data, datatype newdata)
{
    if (parr != NULL)
    {
        datatype *pfind = findfirst(parr, data);
        if (pfind == NULL)
        {
            printf("can not find changeobject error!");
        }
        else
        {
            *pfind = newdata;
        }
    }
    else
    {
        printf("deleteobject error");
    }
}

void changeallobject(struct array *parr, datatype data, datatype newdata)
{
    if (parr!=NULL)
    {
        for (int *pcurr = findfirst(parr, data); pcurr != NULL; pcurr = findfirst(parr, data))
        {
            changefirstobject(parr, data, newdata);
        }
    }
    else
    {
        printf("changeallobject error");
    }
}

datatype * findfirst(struct array *parr, datatype data)
{
    if (parr == NULL || parr->pstart == NULL || parr->length == 0)
    {
        printf("沒有資料咋查詢?");
        return NULL;
    }
    else
    {
        //5 0-4
        datatype *pfind = NULL;
        for (int i = 0; i < parr->length; i++)
        {
            if (data == parr->pstart[i])
            {
                pfind = parr->pstart[i];//parr->pstart+i
                break;
            }
        }
        return pfind;
    }
}

struct Res findall(struct array *parr, datatype data)
{
    struct Res ResA;
    ResA.n = 0;//統計元素個數
    for (int i = 0; i < parr->length; i++)
    {
        if (data==parr->pstart[i])//基本完成
        {
            ResA.n++;
        }
    }
    ResA.ppstat = malloc(sizeof(datatype *)*ResA.n);//分配記憶體[指標陣列佔用]
    int j = 0;//代表下標
    for (int i = 0; i < parr->length; i++)
    {
        if (data==parr->pstart[i])
        {
            ResA.ppstat[j++] = parr->pstart + i;//儲存地址
        }
    }

    return ResA;
}

void show(struct array *parr)
{
    if (parr == NULL || parr->pstart == NULL || parr->length == 0)
    {
        printf("沒有資料咋顯示?");
        return;
    }
    else
    {
        //5 0-4
        printf("\n陣列此時狀態\n");
        for (int i = 0; i < parr->length; i++)
        {
            printf("%4d", parr->pstart[i]);//列印資料
        }
    }
}
///main.c
#include "myarray.h"

void main()
{
    struct array mydata;
    int a[10] = { 1, 2, 6, 4, 5, 6, 7, 8, 9, 6 };
    int b[5] = { 11, 12, 13, 14 };
    int c[4] = { 21, 22, 23, 24 };
    initwitharray(&mydata, a, 10);
    show(&mydata);

    //changeallobject(&mydata, 6, 660);
    //changefirstobject(&mydata,5, 950);
    //insertobjects(&mydata, 8, c, 4);
    //deleteallobject(&mydata, 6);
    //deletefirstobject(&mydata, 6);
    //addobjects(&mydata, b, 5);
    //addobjects(&mydata, c, 4);
    //insertobject(&mydata, 1,999);//根據位置插入

    struct Res res = findall(&mydata, 6);
    for (int i = 0; i < res.n; i++)
    {
        printf("\n%p,%d", res.ppstat[i], *res.ppstat[i]);
    }

    show(&mydata);

    system("pause");
}

相關文章