(vc)分享一个读写ini文件的类,支持多种数据类型的读写,二进制数据都能保存和读取...

本文介绍了一个用于读写INI文件的C++类库,提供了多种数据类型的读写方法,包括字符串、整数、浮点数、双精度浮点数、布尔值、坐标点、矩形区域和颜色值等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读写ini文件的类叫CIni,有ini.h和ini.cpp两个文件组成。

 

 

ini.h文件:

#pragma once


#define SER_GET(bGet,value) SerGet(bGet,value,#value)
#define SER_ARR(bGet,value,n) SerGet(bGet,value,n,#value)
#define SER_GETD(bGet,value,default) SerGet(bGet,value,#value,NULL,default)
#define SER_ARRD(bGet,value,n,default) SerGet(bGet,value,n,#value,default)

class CIni  
{
public:
	// If the IniFilename contains no path,
	// the module-directory will be add to the FileName,
	// to avoid storing in the windows-directory
	// bModulPath=true: ModulDir, bModulPath=false: CurrentDir
	static void AddModulPath(CString& rstrFileName, bool bModulPath = true);
	static CString GetDefaultSection();
	static CString GetDefaultIniFile(bool bModulPath = true);

	CIni();
	CIni(CIni const& rIni);
	CIni(CString const& rstrFileName);
	CIni(CString const& rstrFileName, CString const& rstrSection);
	virtual ~CIni();

	void SetFileName(const CString& rstrFileName);
	void SetSection(const CString& rstrSection);
	const CString& GetFileName() const;
	const CString& GetSection() const;

	CString		GetString(LPCTSTR lpszEntry,	LPCTSTR		lpszDefault = NULL,				LPCTSTR lpszSection = NULL);
	CString		GetStringUTF8(LPCTSTR lpszEntry,LPCTSTR		lpszDefault = NULL,				LPCTSTR lpszSection = NULL);
	CString		GetStringLong(LPCTSTR lpszEntry,LPCTSTR		lpszDefault = NULL,				LPCTSTR lpszSection = NULL);
	double		GetDouble(LPCTSTR lpszEntry,	double		fDefault = 0.0,					LPCTSTR lpszSection = NULL);
	float		GetFloat(LPCTSTR lpszEntry,		float		fDefault = 0.0F,				LPCTSTR lpszSection = NULL);
	int			GetInt(LPCTSTR lpszEntry,		int			nDefault = 0,					LPCTSTR lpszSection = NULL);
	ULONGLONG	GetUInt64(LPCTSTR lpszEntry,	ULONGLONG	nDefault = 0,					LPCTSTR lpszSection = NULL);
	WORD		GetWORD(LPCTSTR lpszEntry,		WORD		nDefault = 0,					LPCTSTR lpszSection = NULL);
	bool		GetBool(LPCTSTR lpszEntry,		bool		bDefault = false,				LPCTSTR lpszSection = NULL);
	CPoint		GetPoint(LPCTSTR lpszEntry,		CPoint		ptDefault = CPoint(0,0),		LPCTSTR lpszSection = NULL);
	CRect		GetRect(LPCTSTR lpszEntry,		CRect		rectDefault = CRect(0,0,0,0),	LPCTSTR lpszSection = NULL);
	COLORREF	GetColRef(LPCTSTR lpszEntry,	COLORREF	crDefault = RGB(128,128,128),	LPCTSTR lpszSection = NULL);
	bool		GetBinary(LPCTSTR lpszEntry,	BYTE** ppData, UINT* pBytes,				LPCTSTR lpszSection = NULL);

	void		WriteString(LPCTSTR lpszEntry,	LPCTSTR		s,								LPCTSTR lpszSection = NULL);
	void		WriteStringUTF8(LPCTSTR lpszEntry,LPCTSTR   s,								LPCTSTR lpszSection = NULL);
	void		WriteDouble(LPCTSTR lpszEntry,	double		f,								LPCTSTR lpszSection = NULL);
	void		WriteFloat(LPCTSTR lpszEntry,	float		f,								LPCTSTR lpszSection = NULL);
	void		WriteInt(LPCTSTR lpszEntry,		int			n,								LPCTSTR lpszSection = NULL);
	void		WriteUInt64(LPCTSTR lpszEntry,	ULONGLONG	n,								LPCTSTR lpszSection = NULL);
	void		WriteWORD(LPCTSTR lpszEntry,	WORD		n,								LPCTSTR lpszSection = NULL);
	void		WriteBool(LPCTSTR lpszEntry,	bool		b,								LPCTSTR lpszSection = NULL);
	void		WritePoint(LPCTSTR lpszEntry,	CPoint		pt,								LPCTSTR lpszSection = NULL);
	void		WriteRect(LPCTSTR lpszEntry,	CRect		rect,							LPCTSTR lpszSection = NULL);
	void		WriteColRef(LPCTSTR lpszEntry,	COLORREF	cr,								LPCTSTR lpszSection = NULL);
	bool		WriteBinary(LPCTSTR lpszEntry,	LPBYTE pData, UINT nBytes,					LPCTSTR lpszSection = NULL);

	void		SerGetString(	bool bGet, CString&		s,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	LPCTSTR lpszDefault = NULL);
	void		SerGetDouble(	bool bGet, double&		f,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	double fDefault = 0.0);
	void		SerGetFloat(	bool bGet, float&		f,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	float fDefault = 0.0);
	void		SerGetInt(		bool bGet, int&			n,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	int nDefault = 0);
	void		SerGetDWORD(	bool bGet, DWORD&		n,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	DWORD nDefault = 0);
	void		SerGetBool(		bool bGet, bool&		b,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	bool bDefault = false);
	void		SerGetPoint(	bool bGet, CPoint&		pt,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	CPoint ptDefault = CPoint(0,0));
	void		SerGetRect(		bool bGet, CRect&		rc,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	CRect rectDefault = CRect(0,0,0,0));
	void		SerGetColRef(	bool bGet, COLORREF&	cr,	LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	COLORREF crDefault = RGB(128,128,128));

	void		SerGet(	bool bGet, CString&	 s,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	LPCTSTR lpszDefault = NULL);
	void		SerGet(	bool bGet, double&	 f,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	double fDefault = 0.0);
	void		SerGet(	bool bGet, float&	 f,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	float fDefault = 0.0F);
	void		SerGet(	bool bGet, int&		 n,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	int nDefault = 0);
	void		SerGet(	bool bGet, short&	 n,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	int nDefault = 0);
	void		SerGet(	bool bGet, DWORD&	 n,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	DWORD nDefault = 0);
	void		SerGet(	bool bGet, WORD&	 n,	 LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	DWORD nDefault = 0);
	void		SerGet(	bool bGet, CPoint&	 pt, LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	CPoint ptDefault = CPoint(0,0));
	void		SerGet(	bool bGet, CRect&	 rc, LPCTSTR lpszEntry,	LPCTSTR lpszSection = NULL,	CRect rectDefault = CRect(0,0,0,0));

	void		SerGet(	bool bGet, CString*	s,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, LPCTSTR lpszDefault = NULL);
	void		SerGet(	bool bGet, double*	f,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, double fDefault = 0.0);
	void		SerGet(	bool bGet, float*	f,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, float fDefault = 0.0F);
	void		SerGet(	bool bGet, BYTE*	n,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, BYTE nDefault = 0);
	void		SerGet(	bool bGet, int*		n,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, int nDefault = 0);
	void		SerGet(	bool bGet, short*	n,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, int nDefault = 0);
	void		SerGet(	bool bGet, DWORD*	n,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, DWORD nDefault = 0);
	void		SerGet(	bool bGet, WORD*	n,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, DWORD nDefault = 0);
	void		SerGet(	bool bGet, CPoint*	pt,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, CPoint ptDefault = CPoint(0,0));
	void		SerGet(	bool bGet, CRect*	rc,	int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, CRect rectDefault = CRect(0,0,0,0));

	int			Parse(const CString&, int nOffset, CString &rstrOut);
	void		DeleteKey(LPCTSTR lpszKey);

private:
	void Init(LPCTSTR lpszIniFile, LPCTSTR lpszSection = NULL);
	LPTSTR GetLPCSTR(LPCTSTR lpszEntry, LPCTSTR lpszSection, LPCTSTR lpszDefault);

	bool  m_bModulPath;  //true: Filenames without path take the Modulepath
	//false: Filenames without path take the CurrentDirectory

#define MAX_INI_BUFFER 256
	TCHAR	m_chBuffer[MAX_INI_BUFFER];
	CString m_strFileName;
	CString m_strSection;

	static CString	Read( LPCTSTR lpszFileName, LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault);
	static void		Write(LPCTSTR lpszFileName, LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue);
};

 

 

 

ini.cpp文件:

#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include ".\ini.h"
#include "StringConversion.h"

#ifndef _countof
#define _countof(array) (sizeof(array)/sizeof(array[0]))
#endif

void CIni::AddModulPath(CString &rstrFileName, bool bModulPath)
{
	TCHAR drive[_MAX_DRIVE];
	TCHAR dir[_MAX_DIR];
	TCHAR fname[_MAX_FNAME];
	TCHAR ext[_MAX_EXT];

	_tsplitpath(rstrFileName, drive, dir, fname, ext);
	if (!drive[0])
	{
		//PathCanonicalize(..) doesn't work with for all Plattforms !
		CString strModule;
		if (bModulPath)
		{
			DWORD dwModPathLen = GetModuleFileName(NULL, strModule.GetBuffer(MAX_PATH), MAX_PATH);
			strModule.ReleaseBuffer((dwModPathLen == 0 || dwModPathLen == MAX_PATH) ? 0 : -1);
		}
		else
		{
			DWORD dwCurDirLen = GetCurrentDirectory(MAX_PATH, strModule.GetBuffer(MAX_PATH));
			strModule.ReleaseBuffer((dwCurDirLen == 0 || dwCurDirLen >= MAX_PATH) ? 0 : -1);
			strModule.TrimRight(_T('\\'));
			strModule.TrimRight(_T('/'));
			strModule += _T("\\");
		}
		_tsplitpath(strModule, drive, dir, fname, ext);
		strModule = drive;
		strModule += dir;
		strModule += rstrFileName;
		rstrFileName = strModule;
	}
}

CString CIni::GetDefaultSection()
{
	return AfxGetAppName();
}

CString CIni::GetDefaultIniFile(bool bModulPath)
{
	TCHAR drive[_MAX_DRIVE];
	TCHAR dir[_MAX_DIR];
	TCHAR fname[_MAX_FNAME];
	TCHAR ext[_MAX_EXT];
	CString strTemp;
	CString strApplName;
	DWORD dwModPathLen = GetModuleFileName(NULL, strTemp.GetBuffer(MAX_PATH), MAX_PATH);
	strTemp.ReleaseBuffer((dwModPathLen == 0 || dwModPathLen == MAX_PATH) ? 0 : -1);
	_tsplitpath( strTemp, drive, dir, fname, ext );
	strTemp = fname;
	strTemp += _T(".ini");
	if (bModulPath)
	{
		strApplName = drive;
		strApplName += dir;
		strApplName += strTemp;
	}
	else
	{
		DWORD dwCurDirLen = GetCurrentDirectory(MAX_PATH, strApplName.GetBuffer(MAX_PATH));
		strApplName.ReleaseBuffer((dwCurDirLen == 0 || dwCurDirLen >= MAX_PATH) ? 0 : -1);
		strApplName.TrimRight(_T('\\'));
		strApplName.TrimRight(_T('/'));
		strApplName += _T("\\");
		strApplName += strTemp;
	}
	return strApplName;
}

CIni::CIni():
m_bModulPath(true)
{
	m_strFileName = GetDefaultIniFile(m_bModulPath);
	m_strSection  = GetDefaultSection();
}

CIni::CIni(CIni const &Ini):
m_strFileName(Ini.m_strFileName),
m_strSection(Ini.m_strSection),
m_bModulPath(Ini.m_bModulPath)
{
	if (m_strFileName.IsEmpty())
		m_strFileName = GetDefaultIniFile(m_bModulPath);
	AddModulPath(m_strFileName, m_bModulPath);
	if (m_strSection.IsEmpty())
		m_strSection = GetDefaultSection();
}

CIni::CIni(CString const &rstrFileName):
m_strFileName(rstrFileName),
m_bModulPath(true)
{
	if (m_strFileName.IsEmpty())
		m_strFileName = GetDefaultIniFile(m_bModulPath);
	AddModulPath(m_strFileName, m_bModulPath);
	m_strSection = GetDefaultSection();
}

CIni::CIni(CString const &rstrFileName, CString const &rstrSection):
m_strFileName(rstrFileName),
m_strSection(rstrSection),
m_bModulPath(true)
{
	if (m_strFileName.IsEmpty())
		m_strFileName = GetDefaultIniFile(m_bModulPath);
	AddModulPath(m_strFileName, m_bModulPath);
	if (m_strSection.IsEmpty())
		m_strSection = GetDefaultSection();
}

CIni::~CIni()
{
}

void CIni::SetFileName(const CString &rstrFileName)
{
	m_strFileName = rstrFileName;
	AddModulPath(m_strFileName);
}

void CIni::SetSection(const CString &rstrSection)
{
	m_strSection = rstrSection;
}

const CString& CIni::GetFileName() const
{
	return m_strFileName;
}

const CString& CIni::GetSection() const
{
	return m_strSection;
}

void CIni::Init(LPCTSTR lpszFileName, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	if (lpszFileName != NULL)
		m_strFileName = lpszFileName;
}

CString CIni::GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSection)
{
	if (lpszDefault == NULL)
		return GetLPCSTR(lpszEntry, lpszSection, _T(""));
	else
		return GetLPCSTR(lpszEntry, lpszSection, lpszDefault);
}

CString CIni::GetStringLong(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSection)
{
	CString ret;
	unsigned int maxstrlen = MAX_INI_BUFFER;

	if (lpszSection != NULL)
		m_strSection = lpszSection;

	do {
		GetPrivateProfileString(m_strSection, lpszEntry, (lpszDefault == NULL) ? _T("") : lpszDefault, 
			ret.GetBufferSetLength(maxstrlen), maxstrlen, m_strFileName);
		ret.ReleaseBuffer();
		if ((unsigned int)ret.GetLength() < maxstrlen - 2)
			break;
		maxstrlen += MAX_INI_BUFFER;
	}
	while (maxstrlen < 32767);

	return ret;
}

CString CIni::GetStringUTF8(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;

	CStringA strUTF8;
	GetPrivateProfileStringA(CT2CA(m_strSection), CT2CA(lpszEntry), CT2CA(lpszDefault),
		strUTF8.GetBufferSetLength(MAX_INI_BUFFER), MAX_INI_BUFFER, CT2CA(m_strFileName));
	strUTF8.ReleaseBuffer();
	return OptUtf8ToStr(strUTF8);
}

double CIni::GetDouble(LPCTSTR lpszEntry, double fDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%g"), fDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	return _tstof(m_chBuffer);
}

float CIni::GetFloat(LPCTSTR lpszEntry, float fDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%g"), fDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	return (float)_tstof(m_chBuffer);
}

int CIni::GetInt(LPCTSTR lpszEntry, int nDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%d"), nDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	return _tstoi(m_chBuffer);
}

ULONGLONG CIni::GetUInt64(LPCTSTR lpszEntry, ULONGLONG nDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%I64u"), nDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	ULONGLONG nResult;
	if (_stscanf(m_chBuffer, _T("%I64u"), &nResult) != 1)
		return nDefault;
	return nResult;
}

WORD CIni::GetWORD(LPCTSTR lpszEntry, WORD nDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%u"), nDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	return (WORD)_tstoi(m_chBuffer);
}

bool CIni::GetBool(LPCTSTR lpszEntry, bool bDefault, LPCTSTR lpszSection)
{
	TCHAR szDefault[MAX_PATH];
	_sntprintf(szDefault, _countof(szDefault), _T("%d"), bDefault);
	szDefault[_countof(szDefault) - 1] = _T('\0');
	GetLPCSTR(lpszEntry, lpszSection, szDefault);
	return _tstoi(m_chBuffer) != 0;
}

CPoint CIni::GetPoint(LPCTSTR lpszEntry, CPoint ptDefault, LPCTSTR lpszSection)
{
	CPoint ptReturn = ptDefault;

	CString strDefault;
	strDefault.Format(_T("(%d,%d)"), ptDefault.x, ptDefault.y);

	CString strPoint = GetString(lpszEntry, strDefault, lpszSection);
	if (_stscanf(strPoint,_T("(%d,%d)"), &ptReturn.x, &ptReturn.y) != 2)
		return ptDefault;

	return ptReturn;
}

CRect CIni::GetRect(LPCTSTR lpszEntry, CRect rectDefault, LPCTSTR lpszSection)
{
	CRect rectReturn = rectDefault;

	CString strDefault;
	strDefault.Format(_T("%d,%d,%d,%d"), rectDefault.left, rectDefault.top, rectDefault.right, rectDefault.bottom);

	CString strRect = GetString(lpszEntry, strDefault, lpszSection);

	//new Version found
	if (_stscanf(strRect, _T("%d,%d,%d,%d"), &rectDefault.left, &rectDefault.top, &rectDefault.right, &rectDefault.bottom) == 4)
		return rectReturn;
	//old Version found
	if (_stscanf(strRect, _T("(%d,%d,%d,%d)"), &rectReturn.top, &rectReturn.left, &rectReturn.bottom, &rectReturn.right) != 4)
		return rectDefault;
	return rectReturn;
}

COLORREF CIni::GetColRef(LPCTSTR lpszEntry, COLORREF crDefault, LPCTSTR lpszSection)
{
	int temp[3] = {	GetRValue(crDefault),
		GetGValue(crDefault),
		GetBValue(crDefault) };

	CString strDefault;
	strDefault.Format(_T("RGB(%hd,%hd,%hd)"), temp[0], temp[1], temp[2]);

	CString strColRef = GetString(lpszEntry, strDefault, lpszSection);
	if (_stscanf(strColRef, _T("RGB(%d,%d,%d)"), temp, temp+1, temp+2) != 3)
		return crDefault;

	return RGB(temp[0], temp[1], temp[2]);
}

void CIni::WriteString(LPCTSTR lpszEntry, LPCTSTR lpsz, LPCTSTR lpszSection)
{
	if (lpszSection != NULL) 
		m_strSection = lpszSection;
	WritePrivateProfileString(m_strSection, lpszEntry, lpsz, m_strFileName);
}

void CIni::WriteStringUTF8(LPCTSTR lpszEntry, LPCTSTR lpsz, LPCTSTR lpszSection)
{
	if (lpszSection != NULL) 
		m_strSection = lpszSection;
	CString str(lpsz);
	WritePrivateProfileStringA(CT2CA(m_strSection), CT2CA(lpszEntry), StrToUtf8(str), CT2CA(m_strFileName));
}

void CIni::WriteDouble(LPCTSTR lpszEntry, double f, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_sntprintf(szBuffer, _countof(szBuffer), _T("%g"), f);
	szBuffer[_countof(szBuffer) - 1] = _T('\0');
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WriteFloat(LPCTSTR lpszEntry, float f, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_sntprintf(szBuffer, _countof(szBuffer), _T("%g"), f);
	szBuffer[_countof(szBuffer) - 1] = _T('\0');
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WriteInt(LPCTSTR lpszEntry, int n, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_itot(n, szBuffer, 10);
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WriteUInt64(LPCTSTR lpszEntry, ULONGLONG n, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_ui64tot(n, szBuffer, 10);
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WriteWORD(LPCTSTR lpszEntry, WORD n, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_ultot(n, szBuffer, 10);
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WriteBool(LPCTSTR lpszEntry, bool b, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	TCHAR szBuffer[MAX_PATH];
	_sntprintf(szBuffer, _countof(szBuffer), _T("%d"), (int)b);
	szBuffer[_countof(szBuffer) - 1] = _T('\0');
	WritePrivateProfileString(m_strSection, lpszEntry, szBuffer, m_strFileName);
}

void CIni::WritePoint(LPCTSTR lpszEntry, CPoint pt, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	CString strBuffer;
	strBuffer.Format(_T("(%d,%d)"), pt.x, pt.y);
	Write(m_strFileName, m_strSection, lpszEntry, strBuffer);
}

void CIni::WriteRect(LPCTSTR lpszEntry, CRect rect, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	CString strBuffer;
	strBuffer.Format(_T("(%d,%d,%d,%d)"), rect.top, rect.left, rect.bottom, rect.right);
	Write(m_strFileName, m_strSection, lpszEntry, strBuffer);
}

void CIni::WriteColRef(LPCTSTR lpszEntry, COLORREF cr, LPCTSTR lpszSection)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;
	CString strBuffer;
	strBuffer.Format(_T("RGB(%d,%d,%d)"), GetRValue(cr), GetGValue(cr), GetBValue(cr));
	Write(m_strFileName, m_strSection, lpszEntry, strBuffer);
}

TCHAR* CIni::GetLPCSTR(LPCTSTR lpszEntry, LPCTSTR lpszSection, LPCTSTR lpszDefault)
{
	if (lpszSection != NULL)
		m_strSection = lpszSection;

	CString strTemp;
	if (lpszDefault == NULL)
		strTemp = Read(m_strFileName, m_strSection, lpszEntry, CString());
	else
		strTemp = Read(m_strFileName, m_strSection, lpszEntry, lpszDefault);

	return (TCHAR *)memcpy(m_chBuffer, (LPCTSTR)strTemp, (strTemp.GetLength() + 1)*sizeof(TCHAR));
}

void CIni::SerGetString(bool bGet, CString &rstr, LPCTSTR lpszEntry, LPCTSTR lpszSection, LPCTSTR lpszDefault)
{
	if (bGet)
		rstr = GetString(lpszEntry, lpszDefault, lpszSection);
	else
		WriteString(lpszEntry, rstr, lpszSection);
}

void CIni::SerGetDouble(bool bGet, double &f, LPCTSTR lpszEntry, LPCTSTR lpszSection, double fDefault)
{
	if (bGet)
		f = GetDouble(lpszEntry, fDefault, lpszSection);
	else
		WriteDouble(lpszEntry, f, lpszSection);
}

void CIni::SerGetFloat(bool bGet, float &f, LPCTSTR lpszEntry, LPCTSTR lpszSection, float fDefault)
{
	if (bGet)
		f = GetFloat(lpszEntry, fDefault, lpszSection);
	else
		WriteFloat(lpszEntry, f, lpszSection);
}

void CIni::SerGetInt(bool bGet, int &n, LPCTSTR lpszEntry, LPCTSTR lpszSection, int nDefault)
{
	if (bGet)
		n = GetInt(lpszEntry, nDefault, lpszSection);
	else
		WriteInt(lpszEntry, n, lpszSection);
}

void CIni::SerGetDWORD(bool bGet, DWORD &n,	LPCTSTR lpszEntry, LPCTSTR lpszSection, DWORD nDefault)
{
	if (bGet)
		n = (DWORD)GetInt(lpszEntry, nDefault, lpszSection);
	else
		WriteInt(lpszEntry, n, lpszSection);
}

void CIni::SerGetBool(bool bGet, bool &b, LPCTSTR lpszEntry, LPCTSTR lpszSection, bool bDefault)
{
	if (bGet)
		b = GetBool(lpszEntry, bDefault, lpszSection);
	else
		WriteBool(lpszEntry, b, lpszSection);
}

void CIni::SerGetPoint(bool bGet, CPoint &pt, LPCTSTR lpszEntry, LPCTSTR lpszSection, CPoint ptDefault)
{
	if (bGet)
		pt = GetPoint(lpszEntry, ptDefault, lpszSection);
	else
		WritePoint(lpszEntry, pt, lpszSection);
}

void CIni::SerGetRect(bool bGet, CRect & rect, LPCTSTR lpszEntry, LPCTSTR lpszSection, CRect rectDefault)
{
	if (bGet)
		rect = GetRect(lpszEntry, rectDefault, lpszSection);
	else
		WriteRect(lpszEntry, rect, lpszSection);
}

void CIni::SerGetColRef(bool bGet, COLORREF &cr, LPCTSTR lpszEntry, LPCTSTR lpszSection, COLORREF crDefault)
{
	if (bGet)
		cr = GetColRef(lpszEntry, crDefault, lpszSection);
	else
		WriteColRef(lpszEntry, cr, lpszSection);
}

void CIni::SerGet(bool bGet, CString &rstr, LPCTSTR lpszEntry, LPCTSTR lpszSection, LPCTSTR lpszDefault)
{
	SerGetString(bGet, rstr, lpszEntry, lpszSection, lpszDefault);
}

void CIni::SerGet(bool bGet, double &f, LPCTSTR lpszEntry, LPCTSTR lpszSection, double fDefault)
{
	SerGetDouble(bGet, f, lpszEntry, lpszSection, fDefault);
}

void CIni::SerGet(bool bGet, float &f, LPCTSTR lpszEntry, LPCTSTR lpszSection, float fDefault)
{
	SerGetFloat(bGet, f, lpszEntry, lpszSection, fDefault);
}

void CIni::SerGet(bool bGet, int &n, LPCTSTR lpszEntry, LPCTSTR lpszSection, int nDefault)
{
	SerGetInt(bGet, n, lpszEntry, lpszSection, nDefault);
}

void CIni::SerGet(bool bGet, short &n, LPCTSTR lpszEntry, LPCTSTR lpszSection, int nDefault)
{
	int nTemp = n;
	SerGetInt(bGet, nTemp, lpszEntry, lpszSection, nDefault);
	n = (short)nTemp;
}

void CIni::SerGet(bool bGet, DWORD &n, LPCTSTR lpszEntry, LPCTSTR lpszSection, DWORD nDefault)
{
	SerGetDWORD(bGet, n, lpszEntry, lpszSection, nDefault);
}

void CIni::SerGet(bool bGet, WORD &n, LPCTSTR lpszEntry, LPCTSTR lpszSection, DWORD nDefault)
{
	DWORD dwTemp = n;
	SerGetDWORD(bGet, dwTemp, lpszEntry, lpszSection, nDefault);
	n = (WORD)dwTemp;
}

void CIni::SerGet(bool bGet, CPoint &pt, LPCTSTR lpszEntry, LPCTSTR lpszSection, CPoint ptDefault)
{
	SerGetPoint(bGet, pt, lpszEntry, lpszSection, ptDefault);
}

void CIni::SerGet(bool bGet, CRect &rect, LPCTSTR lpszEntry, LPCTSTR lpszSection, CRect rectDefault)
{
	SerGetRect(bGet, rect, lpszEntry, lpszSection, rectDefault);
}

void CIni::SerGet(bool bGet, CString *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, LPCTSTR lpszDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, ar[i]);
				if (ar[i].GetLength() == 0)
					ar[i] = lpszDefault;
			}
		} else {
			strBuffer = ar[0];
			for (int i = 1; i < nCount; i++) {
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(ar[i]);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, double *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, double fDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = fDefault;
				else
					ar[i] = _tstof(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%g"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%g"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, float *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, float fDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = fDefault;
				else
					ar[i] = (float)_tstof(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%g"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%g"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, int *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, int iDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = iDefault;
				else
					ar[i] = _tstoi(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%d"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%d"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, unsigned char *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, unsigned char ucDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = ucDefault;
				else
					ar[i] = (unsigned char)_tstoi(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%d"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%d"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, short *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, int iDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = (short)iDefault;
				else
					ar[i] = (short)_tstoi(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%d"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%d"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, DWORD *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, DWORD dwDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if(strTemp.GetLength() == 0)
					ar[i] = dwDefault;
				else
					ar[i] = (DWORD)_tstoi(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%d"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%d"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, WORD *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, DWORD dwDefault)
{
	if (nCount > 0) {
		CString strBuffer;
		if (bGet) {
			strBuffer = GetString(lpszEntry, _T(""), lpszSection);
			CString strTemp;
			int nOffset = 0;
			for (int i = 0; i < nCount; i++) {
				nOffset = Parse(strBuffer, nOffset, strTemp);
				if (strTemp.GetLength() == 0)
					ar[i] = (WORD)dwDefault;
				else
					ar[i] = (WORD)_tstoi(strTemp);
			}
		} else {
			CString strTemp;
			strBuffer.Format(_T("%d"), ar[0]);
			for (int i = 1; i < nCount; i++) {
				strTemp.Format(_T("%d"), ar[i]);
				strBuffer.AppendChar(_T(','));
				strBuffer.Append(strTemp);
			}
			WriteString(lpszEntry, strBuffer, lpszSection);
		}
	}
}

void CIni::SerGet(bool bGet, CPoint * ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, CPoint ptDefault)
{
	CString strBuffer;
	for (int i = 0; i < nCount; i++)
	{
		strBuffer.Format(_T("_%i"), i);
		strBuffer = lpszEntry + strBuffer;
		SerGet(bGet, ar[i], strBuffer, lpszSection, ptDefault);
	}
}

void CIni::SerGet(bool bGet, CRect *ar, int nCount, LPCTSTR lpszEntry, LPCTSTR lpszSection, CRect rcDefault)
{
	CString strBuffer;
	for (int i = 0; i < nCount; i++)
	{
		strBuffer.Format(_T("_%i"), i);
		strBuffer = lpszEntry + strBuffer;
		SerGet(bGet, ar[i], strBuffer, lpszSection, rcDefault);
	}
}

int CIni::Parse(const CString &strIn, int nOffset, CString &strOut)
{
	strOut.Empty();
	int nLength = strIn.GetLength();

	if (nOffset < nLength) {
		if (nOffset != 0 && strIn[nOffset] == _T(','))
			nOffset++;

		while (nOffset < nLength) {
			if (!_istspace((_TUCHAR)strIn[nOffset]))
				break;
			nOffset++;
		}

		while (nOffset < nLength) {
			strOut += strIn[nOffset];
			if (strIn[++nOffset] == _T(','))
				break;
		}
		strOut.Trim();
	}
	return nOffset;
}

CString CIni::Read(LPCTSTR lpszFileName, LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault)
{
	CString strReturn;
	GetPrivateProfileString(lpszSection,
		lpszEntry,
		lpszDefault,
		strReturn.GetBufferSetLength(MAX_INI_BUFFER),
		MAX_INI_BUFFER,
		lpszFileName);
	strReturn.ReleaseBuffer();
	return strReturn;
}

void CIni::Write(LPCTSTR lpszFileName, LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue)
{
	WritePrivateProfileString(lpszSection,
		lpszEntry,
		lpszValue,
		lpszFileName);
}

bool CIni::GetBinary(LPCTSTR lpszEntry, BYTE** ppData, UINT* pBytes, LPCTSTR pszSection)
{
	*ppData = NULL;
	*pBytes = 0;

	CString str = GetString(lpszEntry, NULL, pszSection);
	if (str.IsEmpty())
		return false;
	ASSERT(str.GetLength()%2 == 0);
	INT_PTR nLen = str.GetLength();
	*pBytes = UINT(nLen)/2;
	*ppData = new BYTE[*pBytes];
	for (int i=0;i<nLen;i+=2)
	{
		(*ppData)[i/2] = (BYTE)(((str[i+1] - 'A') << 4) + (str[i] - 'A'));
	}
	return true;
}

bool CIni::WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes, LPCTSTR pszSection)
{
	// convert to string and write out
	LPTSTR lpsz = new TCHAR[nBytes*2+1];
	UINT i;
	for (i = 0; i < nBytes; i++)
	{
		lpsz[i*2] = (TCHAR)((pData[i] & 0x0F) + 'A'); //low nibble
		lpsz[i*2+1] = (TCHAR)(((pData[i] >> 4) & 0x0F) + 'A'); //high nibble
	}
	lpsz[i*2] = 0;


	WriteString(lpszEntry, lpsz, pszSection);
	delete[] lpsz;
	return true;
}

void CIni::DeleteKey(LPCTSTR pszKey)
{
	WritePrivateProfileString(m_strSection, pszKey, NULL, m_strFileName);
}

 

 

 

 

还有一个字符串转换的类库StringConversion.h:

#pragma once
#include <Windows.h>
#include <atlenc.h>


int utf8towc(LPCSTR pcUtf8, UINT uUtf8Size, LPWSTR pwc, UINT uWideCharSize)
{
	LPWSTR pwc0 = pwc;

	while (uUtf8Size && uWideCharSize)
	{
		BYTE ucChar = *pcUtf8++;
		if (ucChar < 0x80)
		{
			uUtf8Size--;
			uWideCharSize--;
			*(pwc++) = ucChar;
		}
		else if ((ucChar & 0xC0) != 0xC0)
		{
			return -1; // Invalid UTF8 string..
		}
		else
		{
			BYTE ucMask = 0xE0;
			UINT uExpectedBytes = 1;
			while ((ucChar & ucMask) == ucMask)
			{
				ucMask |= ucMask >> 1;
				if (++uExpectedBytes > 3)
					return -1; // Invalid UTF8 string..
			}

			if (uUtf8Size <= uExpectedBytes)
				return -1; // Invalid UTF8 string..

			UINT uProcessedBytes = 1 + uExpectedBytes;
			UINT uWideChar = (UINT)(ucChar & ~ucMask);
			if (uExpectedBytes == 1)
			{
				if ((uWideChar & 0x1E) == 0)
					return -1; // Invalid UTF8 string..
			}
			else
			{
				if (uWideChar == 0 && ((BYTE)*pcUtf8 & 0x3F & (ucMask << 1)) == 0)
					return -1; // Invalid UTF8 string..

				if (uExpectedBytes == 2)
				{
					//if (uWideChar == 0x0D && ((BYTE)*pcUtf8 & 0x20))
					//    return -1;
				}
				else if (uExpectedBytes == 3)
				{
					if (uWideChar > 4)
						return -1; // Invalid UTF8 string..
					if (uWideChar == 4 && ((BYTE)*pcUtf8 & 0x30))
						return -1; // Invalid UTF8 string..
				}
			}

			if (uWideCharSize < (UINT)(uExpectedBytes > 2) + 1)
				break; // buffer full

			while (uExpectedBytes--)
			{
				if (((ucChar = (BYTE)*(pcUtf8++)) & 0xC0) != 0x80)
					return -1; // Invalid UTF8 string..
				uWideChar <<= 6;
				uWideChar |= (ucChar & 0x3F);
			}
			uUtf8Size -= uProcessedBytes;

			if (uWideChar < 0x10000)
			{
				uWideCharSize--;
				*(pwc++) = (WCHAR)uWideChar;
			}
			else 
			{
				uWideCharSize -= 2;
				uWideChar -= 0x10000;
				*(pwc++) = (WCHAR)(0xD800 | (uWideChar >> 10));
				*(pwc++) = (WCHAR)(0xDC00 | (uWideChar & 0x03FF));
			}
		}
	}

	return (int)(pwc - pwc0);
}

CString OptUtf8ToStr(const CStringA& rastr)
{
	CStringW wstr;
	int iMaxWideStrLen = rastr.GetLength();
	LPWSTR pwsz = wstr.GetBuffer(iMaxWideStrLen);
	int iWideChars = utf8towc(rastr, rastr.GetLength(), pwsz, iMaxWideStrLen);
	if (iWideChars <= 0)
	{
		// invalid UTF8 string...
		wstr.ReleaseBuffer(0);
		wstr = rastr;				// convert with local codepage
	}
	else
		wstr.ReleaseBuffer(iWideChars);
	return wstr;					// just return the string
}

CStringA wc2utf8(const CStringW& rwstr)
{
	CStringA strUTF8;
	int iChars = AtlUnicodeToUTF8(rwstr, rwstr.GetLength(), NULL, 0);
	if (iChars > 0)
	{
		LPSTR pszUTF8 = strUTF8.GetBuffer(iChars);
		AtlUnicodeToUTF8(rwstr, rwstr.GetLength(), pszUTF8, iChars);
		strUTF8.ReleaseBuffer(iChars);
	}
	return strUTF8;
}

CStringA StrToUtf8(const CString& rstr)
{
	return wc2utf8(rstr);
}

 

 

 

 

下面是测试demo,使用的是mfc,vs2008,贴出关键代码:

void CCIniTest2Dlg::OnBnClickedOk()//读取ini文件
{
	// TODO: 在此添加控件通知处理程序代码
	CIni out;
	LPBYTE msg;
	UINT msgLen;
	out.GetBinary(_T("entry-1"),&msg,&msgLen,_T("root section"));
	msg[msgLen]=NULL;
	::MessageBoxA(NULL,(char*)msg,"section-1 in entry-1",0);
}

void CCIniTest2Dlg::OnBnClickedButton1()//写入ini文件
{
	// TODO: 在此添加控件通知处理程序代码
	CIni in;
	char msg[255];
	sprintf(msg,"百度and谷歌");
	in.WriteBinary(_T("entry-1"),(LPBYTE)msg,(UINT)strlen(msg),_T("root section"));

	in.WriteInt(_T("entry-2"),123456,_T("root section"));
}

 

完成工程下载:http://download.youkuaiyun.com/detail/liyoubaidu/4693142

ps:能给点评论,交流一下呢?

转载于:https://www.cnblogs.com/liyou-blog/archive/2012/10/27/read_and_write_iniFile_with_multi_data_type.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值