• IniFile


    #ifndef __NEWINIFILE_H__
    #define __NEWINIFILE_H__

    #if _MSC_VER > 1000
    #pragma once
    #endif

    #include <stdlib.h>

    #define MIN(A,B) (((A) < (B)) ? (A) : (B))

    #ifndef UNICODE
    typedef char* MyStopStringPtr;
    #else
    typedef wchar_t* MyStopStringPtr;
    #endif

    /*
    * int : 0
    * DWORD : 1
    * short : 2
    * char : 3
    * float : 4
    * double : 5
    */

    enum EnTableDataType
    {
    int_T, DWORD_T, short_T, char_T, float_T, double_T
    };

    class CIniFile
    {
    public:
    CIniFile();
    CIniFile(CString strPathName);
    virtual ~CIniFile();
    public:
    int WriteFloat(CString strSecName, CString strKeyName, float Data);
    BOOL WriteWORD(CString strSecName, CString strKeyName, WORD Data);
    BOOL WriteInt(CString strSecName, CString strKeyName, int Data);
    BOOL WriteShort(CString strSecName, CString strKeyName,short Data);
    BOOL WriteLong(CString strSecName, CString strKeyName, long Data);
    void SetIniPathName(CString strPathName);
    void SetWhitespace(CString strWhitespace);
    CString GetIniPathName();

    int ReadInt(CString strSecName, CString strKeyName, int nDefault);
    float ReadFloat(CString strSecName,CString strKeyName,float fDefault);
    DWORD ReadRGB(CString strSecName,CString strKeyName,DWORD dwDefault);
    CString ReadString(CString strSecName, CString strKeyName, CString strDefault);
    BOOL WriteString(CString strSecName, CString strKeyName, CString strContent);

    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, int **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, DWORD **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, short **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, char **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, float **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, double **lppTableBuffer);
    int ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, void **lppTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, int *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, DWORD *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, short *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, char *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, float *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, double *lpTableBuffer);
    BOOL WriteTableInfo(CString strSecName, int iTableLength, int iDataType, void *lpTableBuffer);

    private:
    CString m_strPathName;
    CString m_strWhitespace;
    };

    #endif //#define __NEWINIFILE_H__

    #include "stdafx.h"
    #include "IniFile.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    //将TCHAR转为char
    //*tchar是TCHAR类型指针,*_char是char类型指针
    void TcharToChar(const TCHAR * tchar, char * _char)
    {
    int iLength;
    //获取字节长度
    iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
    //将tchar值赋给_char
    WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
    }

    //将char转为TCHAR
    void CharToTchar(const char * _char, TCHAR * tchar)
    {
    int iLength;

    iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
    MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
    }

    CIniFile::CIniFile()
    {
    m_strPathName.Empty();
    m_strWhitespace = _T(" , ");
    }

    CIniFile::CIniFile(CString strPathName)
    {
    m_strPathName = strPathName;
    }

    CIniFile::~CIniFile()
    {
    }

    CString CIniFile::GetIniPathName()
    {
    return m_strPathName;
    }

    void CIniFile::SetIniPathName(CString strPathName)
    {
    m_strPathName = strPathName;

    return;
    }

    void CIniFile::SetWhitespace(CString strWhitespace)
    {
    m_strWhitespace = strWhitespace;

    return;
    }

    CString CIniFile::ReadString(CString strSecName, CString strKeyName, CString strDefault)
    {
    TCHAR buf[MAX_PATH];
    ::GetPrivateProfileString(strSecName, strKeyName, strDefault, buf, MAX_PATH, m_strPathName);
    return buf;
    }

    DWORD CIniFile::ReadRGB(CString strSecName, CString strKeyName, DWORD dwDefault)
    {
    DWORD result;
    //CString strDefault=_T("0x0000000");
    CString strDefault;
    strDefault.Format(_T("%u"), dwDefault);
    TCHAR buf[MAX_PATH];
    ::GetPrivateProfileString(strSecName, strKeyName, strDefault, buf, MAX_PATH, m_strPathName);
    char cBuf[MAX_PATH];
    TcharToChar(buf, cBuf);
    sscanf_s(cBuf, "%x", &result);
    DWORD R=result&0x000000FF;
    DWORD G=(result>>8)&0x000000FF;
    DWORD B=(result>>16)&0x000000FF;
    result=(R<<16)+(G<<8)+B;
    return result;
    }


    BOOL CIniFile::WriteString(CString strSecName, CString strKeyName, CString strContent)
    {
    BOOL result;
    result = ::WritePrivateProfileString(strSecName, strKeyName, strContent, m_strPathName);
    return result;
    }

    int CIniFile::ReadInt(CString strSecName, CString strKeyName, int nDefault)
    {
    int result;
    result = ::GetPrivateProfileInt(strSecName, strKeyName, nDefault, m_strPathName);
    return result;
    }

    float CIniFile::ReadFloat(CString strSecName, CString strKeyName, float fDefault)
    {
    CString strDefault;
    strDefault.Format(_T("%4.8f"),fDefault);
    TCHAR buf[MAX_PATH];
    ::GetPrivateProfileString(strSecName, strKeyName, strDefault, buf, MAX_PATH, m_strPathName);
    char cBuf[MAX_PATH];
    TcharToChar(buf, cBuf);
    float result = static_cast<float>(atof(cBuf));
    return result;
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, int **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new int[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(int));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = static_cast<int>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (*lppTableBuffer)[i] = static_cast<int>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, DWORD **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new DWORD[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(DWORD));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = static_cast<DWORD>(strtoul(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (*lppTableBuffer)[i] = static_cast<DWORD>(wcstoul(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, short **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new short[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(short));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = static_cast<short>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (*lppTableBuffer)[i] = static_cast<short>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, char **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new char[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(char));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = static_cast<char>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (*lppTableBuffer)[i] = static_cast<char>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, float **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new float[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(float));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = static_cast<float>(strtod(csTempParse.GetBuffer(0), &lpStopString));
    #else
    (*lppTableBuffer)[i] = static_cast<float>(wcstod(csTempParse.GetBuffer(0), &lpStopString));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, double **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    // To NULL
    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    *lppTableBuffer = new double[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(double));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (*lppTableBuffer)[i] = strtod(csTempParse.GetBuffer(0), &lpStopString);
    #else
    (*lppTableBuffer)[i] = wcstod(csTempParse.GetBuffer(0), &lpStopString);
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }

    return static_cast<int>(enType);
    }

    int CIniFile::ReadTableInfo(CString strSecName, CString strDefault, int nDefault, int *lpiTableLength, void **lppTableBuffer)
    {
    int i;
    int iLength;
    EnTableDataType enType;
    CString strKeyName;
    CString csDataTable;
    CString csTempStore, csTempParse;

    // init
    if(m_strPathName.GetLength() == 0)
    return -1;
    strKeyName = _T("Length");
    iLength = this->ReadInt(strSecName, strKeyName, nDefault);
    strKeyName.Empty();
    if(iLength <= 0 || iLength == nDefault)
    return -1;

    int iTemp;
    strKeyName = _T("Type");
    iTemp = this->ReadInt(strSecName, strKeyName, nDefault);
    if(iTemp < int_T || iTemp > double_T || iTemp == nDefault)
    return -1;
    enType = static_cast<EnTableDataType>(iTemp);
    strKeyName.Empty();

    strKeyName = _T("DataTable");
    csDataTable = this->ReadString(strSecName, strKeyName, strDefault);
    if(csDataTable == strDefault)
    return -1;
    strKeyName.Empty();

    *lppTableBuffer = NULL;

    // Parse
    int iCurCommaPos = 0;
    int iCurSpacePos = 0;
    int iNextPos = 0;
    MyStopStringPtr lpStopString;

    switch(enType)
    {
    case int_T:
    *lppTableBuffer = new int[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(int));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<int *>(*lppTableBuffer))[i] = static_cast<int>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (reinterpret_cast<int *>(*lppTableBuffer))[i] = static_cast<int>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    case DWORD_T:
    *lppTableBuffer = new DWORD[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(DWORD));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<DWORD *>(*lppTableBuffer))[i] = static_cast<DWORD>(strtoul(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (reinterpret_cast<DWORD *>(*lppTableBuffer))[i] = static_cast<DWORD>(wcstoul(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    case short_T:
    *lppTableBuffer = new short[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(short));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<short *>(*lppTableBuffer))[i] = static_cast<short>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (reinterpret_cast<short *>(*lppTableBuffer))[i] = static_cast<short>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    case char_T:
    *lppTableBuffer = new char[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(char));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<char *>(*lppTableBuffer))[i] = static_cast<char>(strtol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #else
    (reinterpret_cast<char *>(*lppTableBuffer))[i] = static_cast<char>(wcstol(csTempParse.GetBuffer(0), &lpStopString, 10));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    case float_T:
    *lppTableBuffer = new float[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(float));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<float *>(*lppTableBuffer))[i] = static_cast<float>(strtod(csTempParse.GetBuffer(0), &lpStopString));
    #else
    (reinterpret_cast<float *>(*lppTableBuffer))[i] = static_cast<float>(wcstod(csTempParse.GetBuffer(0), &lpStopString));
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    case double_T:
    *lppTableBuffer = new double[iLength];
    *lpiTableLength = iLength;
    memset(*lppTableBuffer, 0, iLength*sizeof(double));
    csTempStore = csDataTable;
    csTempParse = csTempStore;
    csTempStore.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    for(i=0; i<iLength; i++)
    {
    #ifndef UNICODE
    (reinterpret_cast<double *>(*lppTableBuffer))[i] = strtod(csTempParse.GetBuffer(0), &lpStopString);
    #else
    (reinterpret_cast<double *>(*lppTableBuffer))[i] = wcstod(csTempParse.GetBuffer(0), &lpStopString);
    #endif
    csTempParse.Empty();

    // Get Next Number Pos
    iCurCommaPos = csTempStore.Find(_T(","));
    iCurSpacePos = csTempStore.Find(_T(" "));
    if(iCurCommaPos != -1 && iCurSpacePos != -1)
    iNextPos = MIN(iCurCommaPos, iCurSpacePos);
    else if(iCurCommaPos != -1 && iCurSpacePos == -1)
    iNextPos = iCurCommaPos;
    else if(iCurCommaPos == -1 && iCurSpacePos != -1)
    iNextPos = iCurSpacePos;
    else
    break;

    csTempParse = csTempStore.Mid(iNextPos);
    csTempStore.Empty();
    csTempParse.TrimLeft(m_strWhitespace.GetBuffer(0));
    csTempStore = csTempParse;
    }
    break;

    default:
    return -1;
    }

    return static_cast<int>(enType);
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, int *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, DWORD *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, short *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, char *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, float *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%f, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%f"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, double *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%f, "), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%f"), lpTableBuffer[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);

    return TRUE;
    }

    BOOL CIniFile::WriteTableInfo(CString strSecName, int iTableLength, int iDataType, void *lpTableBuffer)
    {
    int i;
    EnTableDataType enType;
    CString strKeyName;
    CString csElmVal;
    CString csContent;

    // init
    if(m_strPathName.GetLength() == 0)
    return FALSE;
    if(lpTableBuffer == NULL || iTableLength <= 0)
    return FALSE;
    if(iDataType < int_T || iDataType > double_T)
    return FALSE;
    enType = static_cast<EnTableDataType>(iDataType);

    // load
    strKeyName = _T("Length");
    csContent.Format(_T(" %d"), iTableLength);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    strKeyName = _T("Type");
    csContent.Format(_T(" %d"), iDataType);
    this->WriteString(strSecName, strKeyName, csContent);
    strKeyName.Empty();
    csContent.Empty();

    switch(enType)
    {
    case int_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<int *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<int *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    case DWORD_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<DWORD *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<DWORD *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    case short_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<short *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<short *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    case char_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<char *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<char *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    case float_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<float *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<float *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    case double_T:
    strKeyName = _T("DataTable");
    csContent = _T(" ");
    for(i=0; i<iTableLength-1; i++)
    {
    csElmVal.Format(_T("%d, "), (reinterpret_cast<double *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    }
    csElmVal.Format(_T("%d"), (reinterpret_cast<double *>(lpTableBuffer))[i]);
    csContent += csElmVal;
    csElmVal.Empty();
    this->WriteString(strSecName, strKeyName, csContent);
    break;

    default:
    return FALSE;
    }

    return TRUE;
    }

    BOOL CIniFile::WriteInt(CString strSecName, CString strKeyName, int Data)
    {
    BOOL ret=TRUE;
    CString str;
    str.Format(_T("%d"),Data);
    ret=WriteString(strSecName,strKeyName,str);
    return ret;
    }

    BOOL CIniFile::WriteShort(CString strSecName, CString strKeyName,short Data)
    {
    BOOL ret=TRUE;
    CString str;
    str.Format(_T("%d"),Data);
    ret=WriteString(strSecName,strKeyName,str);
    return ret;
    }

    BOOL CIniFile::WriteWORD(CString strSecName, CString strKeyName, WORD Data)
    {
    BOOL ret=TRUE;
    CString str;
    str.Format(_T("%d"),Data);
    ret=WriteString(strSecName,strKeyName,str);
    return ret;
    }

    int CIniFile::WriteFloat(CString strSecName, CString strKeyName, float Data)
    {
    BOOL ret=TRUE;
    CString str;
    str.Format(_T("%f"),Data);
    ret=WriteString(strSecName,strKeyName,str);
    return ret;
    }


    BOOL CIniFile::WriteLong(CString strSecName, CString strKeyName, long Data)
    {

    BOOL ret=TRUE;
    CString str;
    str.Format(_T("%ld"),Data);
    ret=WriteString(strSecName,strKeyName,str);
    return ret;
    }

  • 相关阅读:
    工具类-vim在shell中卡死的情况
    tomcat日志分类
    逻辑运算
    牛客练习赛29 F 算式子
    牛客练习赛29 B
    查询
    hdu 5984
    zoj 4057
    zoj 4056
    zoj 4054
  • 原文地址:https://www.cnblogs.com/waterair/p/7426719.html
Copyright © 2020-2023  润新知