一个比较完整的CString类

 

//String.h

class CString{

public:

    CString(int iBufferNum);

    CString(char c, int iBufferNum);

    CString(const char *data, int iBufferNum);

    CString(const char *data, long len, int iBufferNum);

    ~CString(void);

 

    CString &operator=(char c);

    const CString& operator=(const char *lpsz);

    const CString& operator=(CString&stringSrc);

    const CString& operator+=(const char *lpsz);

    const CString& operator+=(char ch);

    const CString& operator+=(CString&string);

   

    char operator[](int nIndex) const;

    operator LPCTSTR() const;

 

    CString *Duplicate(int iBufferNum)const;

    CString Left(int count) const;

    CString Right(int count) const;

 

    void SafeDestroy(void);

    void Empty(void);

    void MakeUpper(void);

    void MakeLower(void);

    void TrimLeft(void);

    void TrimRight(void);

    void Trim(void);

    void Defrag(void);

    void Format(char *fmt, ...);

    void AssignNewSpace(int iNewTotalSize,int iNeedMove);

    void ConcatCopy(constchar *str1,int nSrc1Len,constchar *str2,int nSrc2Len);

    void SetAt(long pos,char ch);

    void GetManyChars(char *buf,long pos,long len)const;

    void ReleaseBuffer(int nNewLength);

   

    int CreateFromData(constchar *data,long len);

    int IsEmpty(void)const;

    int Grow(int iBufferNum);

    int Append(constchar *pSrc,int iLen);

    int Append(CString *pNewStr);

    int Compare(constchar *pNewStr)const;

    int CompareNoCase(constchar *pNewStr)const;

    int Find(int ch,long pos)const;

    int Find(constchar *str,long pos)const;

    int Replace(constchar *lpszOld,constchar *lpszNew);

 

    char *GetData(void)const;

    char GetAt(int nIndex)const;

    char *GetBuffer(int nMinBufLength);

   

    long GetLength(void)const;

 

    friend CString operator+(const CString& string1,const CString&string2)

    friend CString operator+(const CString& string,char ch);

    friend CString operator+(char ch, const CString& string);

    friend CString operator+(const CString& string,constchar *lpsz);

    friend CString operator+(const char *lpsz,const CString& string);

    friend bool operator<=(const CString& s1,const CString& s2);

    friend bool operator<=(const CString& s1,constchar* s2);

private:

    char* m_pBuffer,m_pDataStart,m_pDataEnd;

    long m_nLength;

    int m_nSize;

};

 

//String.cpp

#include "String.h"

#include <stdio.h>

#include <stdlib.h>

#include <stdarg.h>

#include <string.h>

#include <ctype.h>

 

#if defined(WIN32)

  #include <windows.h>

#elif defined(linux)

#elif defined(_AIX)

  #include <extension.h>

#else

#endif

 

#ifdef _xlC

  #include <strings.h>

#endif

 

#include "macros.h"

#include "String.h"

using namespace clib;

 

#define STR_PAGE_SIZE

#define SAFEDELETE

 

CString::CString(int iBufferNum)    

{

    m_pBuffer = new char[iBufferNum * STR_PAGE_SIZE];     //动态申请内存

    m_nLength = 0;                                        //长度

    m_nSize   = iBufferNum * STR_PAGE_SIZE;                //字符串大小初始化为iBufferNum个*1024

    m_pDataStart = m_pDataEnd= m_pBuffer;               //开始字符串指针全部指向m_pBuffer

}

 

CString::CString(char c, int iBufferNum)       //参数为字符c和iBufferNum,构造函数

{

    char data[2], len = 2;  

    data[0] = c;                      //将c放在字符数组首位

    data[1] = 0;                      //将字符数组data第二位置为

    if (len > iBufferNum * STR_PAGE_SIZE)      //如果iBufferNum个*1024小于

    {

       m_pBuffer = new char[len + 1]; //为字符串类的主要字符串m_pBuffer动态申请内存空间

       m_nSize   = len + 1;        //字符串大小为

    }

    else

    {

       m_pBuffer = new char[iBufferNum * STR_PAGE_SIZE];    //字符串申请内存空间 

       m_nSize   = iBufferNum * STR_PAGE_SIZE;

    }

    CreateFromData(data,len);            //根据字符数组data开始创建对象m_pDataStart和m_pDataEnd

}

 

CString::CString(const char *data, int iBufferNum)

{

    long len = strlen(data);

    if (len > iBufferNum * STR_PAGE_SIZE)    //字符串的大小大于制定数量个*1024

    {

       m_pBuffer = new char[len + 1]; // 动态申请内存空间

       m_nSize   = len + 1;

    }

    else

    {

       m_pBuffer = new char[iBufferNum * STR_PAGE_SIZE];

       m_nSize   = iBufferNum * STR_PAGE_SIZE;

    }

    CreateFromData(data,len);       //根据字符数组data开始创建对象m_pDataStart和m_pDataEnd 

}

 

CString::CString(const char *data, long len, int iBufferNum)   //构造函数的参数为字符串

{

    if (len > iBufferNum * STR_PAGE_SIZE)        //如果字符串的大小大于制定数量个*1024

    {

       m_pBuffer = new char[len + 1]; // 动态申请内存空间

       m_nSize   = len + 1;

    }

    else

    {

       m_pBuffer = new char[iBufferNum * STR_PAGE_SIZE];

       m_nSize   = iBufferNum * STR_PAGE_SIZE;

    }

    CreateFromData(data,len); //根据字符数组data开始创建对象m_pDataStart和m_pDataEnd 

}

 

CString::~CString(void)

{

    SafeDestroy();

}

 

/*

赋值构造函数

*/

const CString& CString::operator=(constchar *lpsz)

{

    int len = strlen(lpsz);

    if (m_nSize < len) // c + '\0' length

    {// it needs to realloc space, but we use new anddelete pair

       SafeDestroy();

       m_pBuffer = new char[len + 1];

       m_nSize   = len + 1;

       //TODO, I don't check the value of this pointer, unkownresult. :)

    }

    m_pDataStart = m_pBuffer;

    strcpy((char *)m_pDataStart, lpsz);

    m_pDataStart[len] =0;

    m_pDataEnd = &(m_pDataStart[len]);

    m_nLength = len;

    return *this;

}

 

/*

赋值构造函数

*/

const CString& CString::operator+=(constchar *lpsz)

{

    int len = strlen(lpsz);

    if (m_nSize < m_nLength + len +1)

    {

       AssignNewSpace(m_nLength+ len + 1, 1); //allocate new space and move orignal data

    }

    Defrag();

    memcpy(m_pDataEnd, lpsz, len);

    m_pDataEnd += len;

    *m_pDataEnd = 0;

    return *this;

}

 

/*

赋值构造函数

*/

const CString& CString::operator=(CString&stringSrc)      //赋值操作符

{

    long len = stringSrc.GetLength();      //取得stringSrc字符串长度

    if (len >= m_nSize)                    //如果空间大小不够

    {

       AssignNewSpace(len+ 1, 0); // don't copy orignal data      //将会申请一块新的内存空间

    }

    Empty();           //清空

    memcpy(m_pDataStart,stringSrc.GetData(),len);     //将字符串stringSrc复制给新的m_pDataStart

    m_pDataStart[len] =0;

    m_pDataEnd = &(m_pDataStart[len]);                   //获得新的m_pDataEnd

    m_nLength  = len;

    return *this;                                    

}

 

/*

赋值构造函数

*/

CString&CString::operator=(char c)                           //赋值操作符,将字符赋给字符串

{

    if (m_nSize < 2) // c + '\0' length                      //如果内存空间不足

    {

       SafeDestroy();

       m_pBuffer = new char[2];                            //重新申请内存

       m_nSize   = 2;

    }

    m_pDataStart = m_pBuffer;                //获得头指针

    m_pDataStart[0] = c;

    m_pDataStart[1] = 0;

    m_pDataEnd = &(m_pDataStart[1]);         //获得尾指针

    m_nLength  =1;

    return *this;

}

 

/*

赋值构造函数

*/

const CString& CString::operator+=(char ch)

{

    if (m_nSize < m_nLength + 1 + 1)

    {

       AssignNewSpace(m_nLength+ 1 + 1, 1); // allocate new space and move orignaldata

    }

    Defrag();

    memcpy(m_pDataEnd,&ch, 1);

    m_pDataEnd += 1;

    *m_pDataEnd = 0;

    return *this;

}

 

/*

赋值构造函数

*/

const CString& CString::operator+=(CString&string)

{

    if (m_nSize < m_nLength + string.GetLength() + 1)

    {

       AssignNewSpace(m_nLength+ string.GetLength()+ 1, 1); // allocate new space and move orignal data

    }

    Defrag();

    memcpy(m_pDataEnd, string.GetData(), string.GetLength());

    m_pDataEnd += string.GetLength();

    *m_pDataEnd = 0;

    return *this;

}

 

/*

获取指定位置字符

*/

char CString::operator[](int nIndex)const

{

    if (nIndex >= m_nLength)

       return -1;

    return m_pDataStart[nIndex];

}

 

/*

获取常量字符串指针

*/

CString::operator LPCTSTR() const             //将该字符串转变为const char*字符串常量

{

    return (constchar*)m_pDataStart;

}

 

 

/*

复制本对象的前n个字符的字符串的对象,返回指向该对象的指针

*/

CString*CString::Duplicate(int iBufferNum)const

{

    CString *pCStr = NULL;

    pCStr = new CString(m_pDataStart,m_nLength, iBufferNum);

 

    return pCStr;

}

 

 

/*

返回左边n个字符的字符串

*/

CString CString::Left(int count) const

{

    if (count < 0)

       count = 0;

    if (count >= m_nLength)

       return *this;

    CString dest(m_pDataStart, count);  //调用构造函数新建一个

    return dest;

}

 

/*

返回右边n个字符的字符串

*/

CString CString::Right(int count)const

{

    if (count < 0)

       count = 0;

    if (count >= m_nLength)

       return *this;

    CString dest(&(m_pDataStart[m_nLength- count]), count);

    return dest;

}

 

/*

返回指向字符串起始位置的指针

*/

char*CString::GetData(void)const         //获得指向该字符串的头部指针

{

    return m_pDataStart;

}

 

/*

返回指向字符串起始位置的指针

*/

char*CString::GetBuffer(int nMinBufLength)    //获得该字符串头指针,并且说明返回的内存空间最小值

{

    Defrag();

    if (nMinBufLength> m_nLength)

       AssignNewSpace(nMinBufLength,1);

    return m_pDataStart;

}

 

 

/*

替换字符串

*/

int CString::Replace(constchar *lpszOld,constchar *lpszNew)

{

    if (!lpszOld)

       return 0;

    int nOldLen = strlen(lpszOld);      //获得旧字符串的长度

    if (nOldLen <= 0)

       return 0;

    int nNewLen = strlen(lpszNew);       //获得新字符串的长度

 

    int nCount = 0;

    char *lpszStart = m_pDataStart;                  

    char *lpszEnd = m_pDataEnd;

    char *lpszTarget;

    while (lpszStart< lpszEnd)                  //循环处理原有字符串

    {

       while ((lpszTarget =strstr(lpszStart,lpszOld)) != NULL)    //如果在字符串lpszStart中发现子串lpszOld

       {

           nCount++;                                          //子串数量+1

           lpszStart = lpszTarget+ nOldLen;                    //往后定位字符串lpszStart,从第一个子串后开始

       }

       lpszStart += strlen(lpszStart) + 1;                     //往后查找

    }

    if (nCount >0)                                      //如果有重复的字符串

    {

       int nNewLength=  m_nLength+ (nNewLen - nOldLen)* nCount;  //覆盖后总字符串的大小

       AssignNewSpace(nNewLength+ 1, 1);                         //为新的字符串分配内存空间

       lpszStart = m_pDataStart;                                //重新初始化m_pDataStart,lpszStart,lpszEnd

       lpszEnd = m_pDataEnd;

       while (lpszStart< lpszEnd)                              //循环处理原来的字符串

       {

           while ( (lpszTarget= strstr(lpszStart,lpszOld)) != NULL)       //如果在字符串lpszStart中发现子串lpszOld

           {

              int nBalance = lpszEnd - (lpszTarget+ nOldLen);            //字符串lpszTarget后面的字符数量

              memmove(lpszTarget+ nNewLen, lpszTarget+ nOldLen,

                  nBalance * sizeof(char));    //移走lpszTarget原来的字符串,并为lpszTarget重新设置为nNewLen大小内存

              memcpy(lpszTarget, lpszNew, nNewLen * sizeof(char));   //将新字符串lpszNew覆盖旧的子串lpszTarget

              lpszStart = lpszTarget+ nNewLen;                   //寻找目标字符串后移nNewLen

              lpszStart[nBalance]= '\0';

           }

           lpszStart += strlen(lpszStart) + 1;      //寻找目标字符串往后走

       }

       m_nLength = nNewLength;                     

    }

    return nCount;

}

 

/*

将另一个CString字符串附加到本对象末尾

*/

int CString::Append(CString *pNewStr)

{

    char *pNewStart = NULL, *pSrc = NULL, *pDest = NULL;

    int len = pNewStr->GetLength();      //新添加子串的长度

    int total_len;

    if (len <= 0)

       return 0;

    pSrc = pNewStr->GetData();          //获得要添加的字符串的头指针

    if (!pSrc)

       return 0;

    total_len = m_nLength+ len;        //新字符串的总长度=原来字符串长度+ 添加字符串长度

    if (m_nSize - (m_pDataEnd - m_pBuffer)< len && m_pDataStart- m_pBuffer > 0)

    {

       Defrag();

    }

    AssignNewSpace(total_len+ 1, 1);      根据total_len分配新的内存空间

    pNewStart = m_pDataEnd;                   //将原来字符串的末尾指针转变成新添加子串的开始指针

    if (!pNewStart)

       return 0;

    memcpy(pNewStart, pSrc, len);          //将新添加串pSrc放置在原来串联的末尾

    m_nLength = total_len;

    m_pDataStart[m_nLength]= 0;

    m_pDataEnd = &(m_pDataStart[m_nLength]);     //让m_pDataEnd指向新的字符串的末尾指针

    return 1;

}

 

/*

根据指定字符串重新创建对象

*/

int CString::CreateFromData(constchar *data,long len)        //根据data和长度len创建对象

{

    Empty();      //清空

    if (len <=0)  

       return TRUE;

    if (data == NULL)

       return TRUE;

    if (len > m_nSize)

       return FALSE;

    memcpy(m_pDataStart,data, len);    //将字符数组复制给m_pDataStart指向内存空间

    m_nLength = len;             

    m_pDataStart[m_nLength]= '\0';     

    m_pDataEnd = &(m_pDataStart[m_nLength]);     //取得尾指针m_pDataEnd

    return TRUE;

}

 

/*

判断字符串长度是否为

*/

int CString::IsEmpty(void)const

{

    return !m_nLength;

}

 

/*

分配新的内存空间

*/

int CString::Grow(int iBufferNum)

{

    if (iBufferNum <=0) 

       return 0;

    AssignNewSpace(m_nSize+ iBufferNum * STR_PAGE_SIZE,1);    //分配新的内存空间,变为原来的两倍,移动倍

    return 1;

}

 

/*

添加指定字符串到末尾

*/

int CString::Append(constchar *pSrc,int iLen)

{

    int total_len;

    char *pNewStart = NULL;

    if (iLen <= 0)

       return 0;

    total_len = m_nLength+ iLen;       //append后的总的字符串长度

    if (m_nSize > total_len)            //如果原来总内存空间长度大于append后的字符串长度

    {

       //如果原来剩余空闲空间小于新添加子字符串的长度,而且

       if (m_nSize - (m_pDataEnd - m_pBuffer)< iLen && m_pDataStart- m_pBuffer > 0) //而且m_pDataStart在m_pBuffer的后面

       {

           Defrag();      //调节原来的字符串

       }

    }

    else                                //如果原来总内存空间长小于append后的字符串长度,需要开辟新空间

    {

       AssignNewSpace(total_len+ 1, 1);        //分配新的内存空间,变为原来的两倍,移动倍

    }

    pNewStart = m_pDataEnd;//将原来字符串的末尾指针转变成新添加子串的开始指针

    if (!pNewStart)

       return 0;

    memcpy(pNewStart, pSrc, iLen);    //将新添加串pSrc放置在原来串联的末尾

    m_nLength = total_len;            //字符串的总长度变化

    m_pDataStart[m_nLength]= 0;      //新的字符串最后以为置为

    m_pDataEnd = &(m_pDataStart[m_nLength]);  //让m_pDataEnd指向新的字符串的末尾指针

    return 1;

}

 

/*

比较两个字符串是否相等

*/

int CString::Compare(constchar *pNewStr)const

{

    if (pNewStr == NULL)

       return -1;

    return strcmp(m_pDataStart, pNewStr);     

}

 

/*

比较两个字符串是否相等(不区分大小写)

*/

int CString::CompareNoCase(constchar *pNewStr)const

{

    if (pNewStr == NULL)

       return -1;

#ifndef WIN32

    return strcasecmp(m_pDataStart, pNewStr);

#else

    return stricmp(m_pDataStart, pNewStr);

#endif

}

 

/*

寻找指定字符在字符串中起始位置

*/

int CString::Find(int ch,long pos)const

{

    char *p = NULL;

    if (ch < 0)

       return -1;

    if (ch > UCHAR_MAX)

       return -1;

    if (pos < 0)

       return -1;

    if (pos >= m_nLength)

       return -1;

    p = (char*)memchr(m_pDataStart+ pos, ch, m_nLength - pos);

    if (!p)

       return -1;

    return p - m_pDataStart;

}

 

/*

寻找指定字符串在字符串中起始位置

*/

int CString::Find(constchar *str,long pos)const

{

    long len;

    char *p = NULL;

    if (str == NULL)

       return -1;

    len = strlen(str);

 

    if (len == 0)

       return 0;

    p = (char *)strstr(m_pDataStart+ pos, str);

    if (p == NULL)

       return -1;

    else

       return p - m_pDataStart;

}

 

/*

获取字符串的长度

*/

long CString::GetLength(void)const

{

    return m_nLength;

}

 

 

/*

获取指定位置字符

*/

char CString::GetAt(int nIndex)const

{

    if (nIndex >= m_nLength)     

       return -1;

    if (nIndex < 0)

       return -1;

    return m_pDataStart[nIndex];    

}

 

 

/*

释放内存

*/

void CString::SafeDestroy(void)

{

    SAFEDELETE(m_pBuffer);

    m_nSize = 0;

    Empty();

}

 

/*

重新初始化

*/

void CString::Empty(void)               

{

    memset(m_pBuffer,0, m_nSize);

    m_pDataStart = m_pDataEnd= m_pBuffer;        //将该字符串的头指针和尾指针全部指向字符串的头部

    m_nLength = 0;                               //字符串长度置为

}

 

/*

初始化

*/

void CString::Defrag(void)

{

    //重新初始化原来字符串头指针m_pDataStart,指向头部

    memmove(m_pBuffer, m_pDataStart, m_nLength);    //将m_pDataStart复制给m_pBuffer

    m_pDataStart = m_pBuffer;                        //m_pDataStart指向m_pBuffer

    m_pDataStart[m_nLength]= 0;                   

    m_pDataEnd = &(m_pDataStart[m_nLength]);           //重新获得原来的字符串尾指针m_pDataEnd 

}

 

/*

更改字符串某一位置的值

*/

void CString::SetAt(long pos,char ch)

{

    if (pos < m_nLength)

       m_pDataStart[pos] =ch;

    return;

}

 

/*

获取从给定位置开始n个字符的字符串

*/

void CString::GetManyChars(char *buf,long pos,long len)const

{

    if (buf == NULL)

       return;

    if (pos >= m_nLength)

       return;

    if (pos + len > m_nLength)

       len = m_nLength - pos;

    if (len > 0)

       memcpy(buf, m_pDataStart + pos,len);   //将m_pDataStart + pos开始长为len的子串复制给buf

}

 

void CString::ReleaseBuffer(int nNewLength)

{

    return;

}

 

void CString::MakeUpper(void)

{

    strupr(m_pDataStart);

}

 

void CString::MakeLower(void)

{

    strlwr(m_pDataStart);

}

 

void CString::TrimLeft(void)   // //将字符串右边的空格去掉

{

    int start = 0;

    while (isspace(m_pDataStart[start])&& start < m_nLength)

       start ++;

    if (start > 0)

    {

       m_pDataStart += start;

    }

}

 

void CString::TrimRight(void)       //将字符串右边的空格去掉

{

    int end = m_nLength - 1;

    while (isspace(m_pDataStart[end])&& end >= 0)

       end --;

    if (end < 0)

    {

       end = 0;

       m_pDataEnd = &(m_pDataStart[end]);

    }

    else

    {

       m_pDataEnd = &(m_pDataStart[end]);

 

    }

}

 

void CString::Trim(void)         // //将字符串的空格去掉

{

    TrimLeft();

    TrimRight();

}

 

void CString::Format(char *fmt, ...)

{

    char TmpBuffer[STR_PAGE_SIZE];// TODO,should calculate this size dynamically.

    va_list argList;

    va_start(argList, fmt);

#ifdef WIN32

    _vsnprintf(TmpBuffer,STR_PAGE_SIZE, fmt,argList); // justnot overwrite something

#else

    vsnprintf(TmpBuffer,STR_PAGE_SIZE, fmt,argList); // justnot overwrite something

#endif

    va_end(argList);

}

 

void CString::AssignNewSpace(int iNewTotalSize,int iNeedMove)

{

    char *pNewSpace = NULL;       //新的字符串指针,初始化NULL

    if (iNewTotalSize<= m_nSize)         //确保新的内存空间大于原来的内存空间

       return ;

    // allocate new space

    pNewSpace = new char [iNewTotalSize];     //pNewSpace动态申请内存空间

    if (pNewSpace == NULL)

       return ;

    if (iNeedMove)               

    {

       memcpy(pNewSpace, m_pDataStart, m_nLength+ 1); //将原有字符串复制给新申请内存

    }

    SAFEDELETE(m_pBuffer);              //安全删除原有的字符串m_pBuffer

    m_pBuffer    =pNewSpace;  

    m_pDataStart = m_pBuffer;

    m_pDataEnd   =&(m_pDataStart[m_nLength]);       //重置m_pBuffer,m_pDataStart,m_pDataEnd

    m_nSize = iNewTotalSize;

}

 

/*

连接两个字符串

*/

void CString::ConcatCopy(constchar *str1,int nSrc1Len,constchar *str2,int nSrc2Len)

{

    int nNewLen = nSrc1Len + nSrc2Len;

    AssignNewSpace(nNewLen+ 1, 0);

    // append two string

    Append(str1, nSrc1Len);

    Append(str2, nSrc2Len);

}

 

/*

连接两个字符串

*/

CString operator+(const CString& string1,const CString&string2)

{

    CString s;

    s.ConcatCopy(string1.GetData(), string1.GetLength(),string2.GetData(),string2.GetLength());

    return s;

}

 

/*

连接两个字符串

*/

CString operator+(const CString& string,char ch)

{

    CString s;

    char str[2];

    str[0] = ch;

    str[1] = 0;

    s.ConcatCopy(string.GetData(), string.GetLength(),str, 1);

    return s;

}

 

/*

连接两个字符串

*/

CString operator+(char ch,const CString& string)

{

    CString s;

    char str[2];

    str[0] = ch;

    str[1] = 0;

    s.ConcatCopy(string.GetData(), string.GetLength(),str, 1);

    return s;

}

 

/*

连接两个字符串

*/

CString operator+(const CString& string,constchar *lpsz)

{

    CString s;

    s.ConcatCopy(string.GetData(), string.GetLength(),lpsz, strlen(lpsz));

    return s;

}

 

/*

连接两个字符串

*/

CString operator+(constchar *lpsz,const CString& string)

{

    CString s;

    s.ConcatCopy(string.GetData(), string.GetLength(),lpsz, strlen(lpsz));

    return s;

}

 

/*

比较两个字符串的大小

*/

bool operator<=(const CString& s1,const CString& s2)

{

    return (s1.Compare(s2.GetData()) <= 0);

}

 

/*

比较两个字符串的大小

*/

bool operator<=(const CString& s1,constchar* s2)

{

    return (s1.Compare(s2) <=0);

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值