读写ini文件

来源:互联网 发布:淘宝美工基础教程视频 编辑:程序博客网 时间:2024/05/16 19:03

本文采用两种方法实现读写ini文件,第一种方法是自己封装的类,实现读写ini  ,第二种方法是采用API函数,实现读写ini 文件;

方法一:

.ini文件是项目配置文件,本功能完成读取和写入.ini文件,其实现过程完成读字符串、写字符串、读二进制、写二进制、读整数、写整数、读double、写double八个函数;在函数实现过程中分别调用Readini()Writeini()两个函数来完成读写过程,Readini()、Writeini()是封装在CIniFile类里的读写函数。

tstdlibs.h

#ifndef _TSTDLIBS_H
#define _TSTDLIBS_H


#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdlib.h>

#ifdef _WIN32
#include <tchar.h> // For _T() macro!
#else // Non Windows Platform!
#ifdef _UNICODE
typedef wchar_t TCHAR;
#ifndef _T
#define _T(s) L##s
#endif
#ifndef _TSTR
#define _TSTR(s) L##s
   #endif
#else
   typedef wchar_t TCHAR;
#ifndef _T
#define _T(s) s
#endif
#ifndef _TSTR
       #define _TSTR(s) s
           
#endif
#endif
#endif


namespace tstd                           
{
#ifdef _UNICODE
//typedef std::wstringtstring;
typedef std::wostreamtostream;
typedef std::wistreamtistream;
typedef std::wiostreamtiostream;
typedef std::wistringstreamtistringstream;
typedef std::wostringstreamtostringstream;
typedef std::wstringstreamtstringstream;         
typedef std::wifstreamtifstream;
typedef std::wofstreamtofstream;
typedef std::wfstreamtfstream;
typedef std::wfilebuftfilebuf;
typedef std::wios   tios;
typedef std::wstreambuftstreambuf;
typedef std::wstreampoststreampos;
typedef std::wstringbuftstringbuf;


// declare an unnamed namespace as a superior alternative to the use of global static variable declarations.
namespace
{
    tostream& tcout = std::wcout;
tostream& tcerr = std::wcerr;
tostream& tclog = std::wclog;
tistream& tcin= std::wcin;


    std::wostream& tendl( std::wostream& output )
    {
        output << std::endl;
        return output;
    }


tstring wstr_to_tstr(const std::wstring& arg)
{
return arg;
}


tstring str_to_tstr(const std::string& arg)
{
tstring res(arg.length(), L'\0');
mbstowcs_s(NULL,const_cast<wchar_t*>(res.data()),MAX_PATH ,arg.c_str(),arg.length());
return res;
}


std::wstring tstr_to_wstr(const tstring& arg)
{
return arg;
}


std::string tstr_to_str(const tstring& arg)
{
std::string res(arg.length(), '\0');
wcstombs_s(NULL,const_cast<char*>(res.data()),MAX_PATH,arg.c_str(), arg.length());
return res;
}
}


#else


//typedef std::string   tstring;
typedef std::ostreamtostream;
typedef std::istreamtistream;
typedef std::iostreamtiostream;
typedef std::istringstreamtistringstream;
typedef std::ostringstreamtostringstream;
typedef std::stringstreamtstringstream;
typedef std::ifstreamtifstream;
typedef std::ofstreamtofstream;
typedef std::fstreamtfstream;
typedef std::filebuftfilebuf;
typedef std::iostios;
typedef std::streambuftstreambuf;
typedef std::streampoststreampos;
typedef std::stringbuftstringbuf;


// declare an unnamed namespace as a superior alternative to the use of global static variable declarations.
namespace
{
    tostream& tcout = std::cout;
tostream& tcerr = std::cerr;
tostream& tclog = std::clog;
tistream& tcin= std::cin;


    std::ostream& tendl( std::ostream& output )
    {
        output << std::endl;
        return output;
    }


tstring wstr_to_tstr(const std::wstring& arg)
{
tstring res( arg.length(), '\0' );
wcstombs( const_cast<char*>(res.data()) , arg.c_str(), arg.length());
           return res;
}


tstring str_to_tstr(const std::string& arg)
{
return arg;
}


std::wstring tstr_to_wstr(const tstring& arg)
{
std::wstring res(arg.length(), L'\0');
        mbstowcs(const_cast<wchar_t*>(res.data()), arg.c_str(), arg.length());
        return res;
}


    std::string tstr_to_str(const tstring& arg)
    {
        return arg;
    }
}


#endif
}

#endif

inifile.h

//读写ini
//*******************************************************************************************************************************


#ifndef __CINIFILE_H_
#define __CINIFILE_H_

#include <set>
#include <algorithm>
#include <fstream>

#ifdef _UNICODE
typedef std::wfstream tfstream;
typedef std::wifstream tifstream;
typedef std::wofstream tofstream;
#else
typedef std::fstream tfstream;
typedef std::ifstream tifstream;
typedef std::ofstream tofstream;
#endif


class CIniFile;
class CFileName;


class CSaveFileName
{
friend class CFileName; 
private: 
CSaveFileName( CFileName* pFileName , const tstring& sFileName );
~CSaveFileName();
public:
CFileName* m_pFileName;
tstring m_sFileName;
public:
CIniFile*  m_pIniFile;
};
struct cfn_less_w
{
bool operator() (const CSaveFileName* s1, const CSaveFileName* s2) const
{
#ifndef _WIN32
return wcscasecmp(s1->m_sFileName.c_str(), s2->m_sFileName.c_str()) < 0;
#else
return _wcsicmp(s1->m_sFileName.c_str(), s2->m_sFileName.c_str()) < 0;
#endif
}
};
typedef std::set<CSaveFileName*,cfn_less_w> FileIndex; 


class CFileName
{
public:
CFileName();
~CFileName();


public:
CSaveFileName* GetFileName( tstring sFileName );

private:
FileIndex::const_iterator _find_file( const tstring& sFileName ) const;
FileIndex::iterator  _find_file( const tstring& sFileName );
void RemoveAllFileNames();
FileIndex m_FileNames;
};


class CIniKey
{
friend class CIniSection; // Allow CIniSectionW to create keys  
private: // CIniFileW acts as a class factory for CIniSectionW Objects 
CIniKey( CIniSection* pSection , const tstring& sKeyName );
CIniKey( const CIniKey& ); // No Copy
CIniKey& operator=(const CIniKey&); // No Copy
~CIniKey( );
public:
// Sets the value of the key       
void SetValue( const tstring& sValue );
// Returns the value of the key   
std::wstring GetValue() const;
// Sets the key name, returns true on success, fails if the section  
// name sKeyName already exists
bool SetKeyName( tstring sKeyName );
// Returns the name of the Key   
tstring GetKeyName() const;
public:
// Pointer to the parent CIniSectionW
CIniSection* m_pSection;
// Name of the Key   
tstring m_sKeyName;
// Value associated  
tstring m_sValue;
}; // End of CIniKeyW


// Typedef of set of CIniKeyW pointers  
struct ckey_less_w
{
bool operator() (const CIniKey* s1, const CIniKey* s2) const
{
#ifndef _WIN32
return wcscasecmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
#else
return _wcsicmp(s1->m_sKeyName.c_str(), s2->m_sKeyName.c_str()) < 0;
#endif
}
};
//将CIniKeyW按照ci_less_a排序准则进行排序,排序后的数据存储在set
typedef std::set<CIniKey*,ckey_less_w> KeyIndex;  


class CIniSection
{
friend class CIniFile; // Allow CIniFileW to create sections  
public:


private: // CIniSectionW acts as a class factory for CIniKeyW Objects  
CIniSection( CIniFile* pIniFile , const tstring& sSectionName );
CIniSection( const CIniSection& ); // No Copy
CIniSection& operator=(const CIniSection&); // No Copy
~CIniSection( );
public:
// Adds a key to the CIniSectionW object, returns a CIniKeyW pointer to the new or existing object 
CIniKey* AddKey( tstring sKeyName );
// Removes a single key by pointer  
void RemoveKey( CIniKey* pKey );
// Removes a single key by string
void RemoveKey( tstring sKey );
// Removes all the keys in the section
void RemoveAllKeys( );
// Returns a CIniKeyW pointer to the key by name, NULL if it was not found
CIniKey* GetKey( tstring sKeyName ) const;
// Returns all keys in the section by KeyIndex only to be used for enumeration
const KeyIndex& GetKeys() const;
// Returns a KeyValue at a certain section   
tstring GetKeyValue( tstring sKey ) const;
// Sets a KeyValuePair at a certain section   
void SetKeyValue( tstring sKey, const tstring& sValue );
// Sets the section name, returns true on success, fails if the section
// name sSectionName already exists   
bool SetSectionName( tstring sSectionName );
// Returns the section name
tstring GetSectionName() const;
public:
KeyIndex::const_iterator _find_key( const tstring& sKeyName ) const;  
KeyIndex::iterator _find_key( const tstring& sKeyName );
public:
// CIniFileW pointer back to the object that instanciated the section
CIniFile* m_pIniFile;
// Name of the section
tstring m_sSectionName;
// List of CIniKeyW pointers ( Keys in the section )
KeyIndex m_keys;
}; // End of CIniSectionW


// Typedef of a List of CIniSectionW pointers
struct csec_less_w
{
bool operator() (const CIniSection* s1, const CIniSection* s2) const  //
{
#ifndef _WIN32
return wcscasecmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
#else
return _wcsicmp(s1->m_sSectionName.c_str(), s2->m_sSectionName.c_str()) < 0;
#endif
}
};


typedef std::set<CIniSection*,csec_less_w> SecIndex;
//将CIniSectionW按照ci_less_a排序准则进行排序,排序后的数据存储在set


class CIniFile
{
public:
tfstream m_input;
static const wchar_t* const LF;
public:
CIniFile(const tstring& fileName);
~CIniFile();


// Save data to an output stream    
void Save();
// Load data from an input stream  
void Load(bool bMerge = false );


//写ini文件
bool  CIniFile::Writeini (LPCTSTR sSection,LPCTSTR sKeyName,LPCTSTR sValue ,LPCTSTR fileName);
//读ini文件
tstring CIniFile::Readini(LPCTSTR sSection,LPCTSTR sKeyName, LPWSTR sValue , LPCTSTR  lpszDefaultValue,LPCTSTR fileName,size_t cchValueMax);


public:
// Adds a section to the CIniFileW object, returns a CIniFileW pointer to the new or existing object
CIniSection* AddSection( tstring sSection );
// Removes section by pointer
void RemoveSection( CIniSection* pSection );
// Removes a section by its name sSection
void RemoveSection( tstring sSection );
// Removes all existing sections
void RemoveAllSections( );
// Returns a CIniSectionW* to the section by name, NULL if it was not found
CIniSection* GetSection( tstring sSection ) const;
// Returns all sections in the inifile by SecIndex, only to be used for enumeration (DO NOT KEEP THE REF OR TRY TO DELETE STUFF!)
const SecIndex& GetSections() const;
// Returns a KeyValue at a certain section
tstring GetKeyValue( const tstring& sSection, const tstring& sKey ) const;
// Sets a KeyValuePair at a certain section
void SetKeyValue( const tstring& sSection, const tstring& sKey, const tstring& sValue );
// Renames an existing section returns true on success, false if the section didn't exist or there was another section with the same sNewSectionName
bool RenameSection( const tstring& sSectionName  , const tstring& sNewSectionName );
// Renames an existing key returns true on success, false if the key didn't exist or there was another section with the same sNewSectionName
bool RenameKey( const tstring& sSectionName  , const tstring& sKeyName , const tstring& sNewKeyName);
CFileName* PFileName;
public:
SecIndex::const_iterator _find_sec( const tstring& sSection ) const;
SecIndex::iterator _find_sec( const tstring& sSection );
private:
CIniFile( const CIniFile&); // No Copy
CIniFile& operator=(const CIniFile&); // No Copy
public:
// List of CIniSectionW pointers ( List of sections in the class )
SecIndex m_sections;
tstring m_strFileName;
}; // End of CIniFileW

#endif

Profile.h



#pragma once
#include "inifile.h"
#include "CoreMain.h"


class CProfile
{
public:
CProfile(void);
~CProfile(void);
VOID Init();
VOID UnInit();
INT ReadProfileString(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue, __in size_t cchValueMax, __in_opt LPTSTR lpszDefaultValue);
SSN_RETURN WriteProfileString(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in LPCTSTR lpszValue);


INT ReadProfileBinary(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __inout BYTE* pData, __in UINT nBytes);
SSN_RETURN WriteProfileBinary(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in BYTE* pData, __in UINT nBytes);


INT ReadProfileInt(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in_opt INT nDefault);
SSN_RETURN WriteProfileInt(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in INT nValue);


DOUBLE ReadProfileDouble(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in_opt DOUBLE dDefault);
SSN_RETURN WriteProfileDouble(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in DOUBLE dValue);
CFileName  m_FileName;

};

inifile.cpp

#include "StdAfx.h"
#include "inifile.h"
#include <algorithm>
#include <iostream>
#include <fstream>




#ifdef _WIN32 // Windows default is \r\n
#ifdef _FORCE_UNIX_LINEFEED
#define _CRLFA "\n"
#define _CRLFW L"\n"
#else
#define _CRLFA "\r\n"
#define _CRLFW L"\r\n"
#endif


#else // Standard format is \n for unix
#ifdef _FORCE_WINDOWS_LINEFEED
#define _CRLFA "\r\n"
#define _CRLFW L"\r\n"
#else
#define _CRLFA "\n"
#define _CRLFW L"\n"
#endif
#endif


// Convert wstring to string    
std::string wstr_to_str(const std::wstring& arg)
{
std::string res( arg.length(), '\0' );
wcstombs_s(NULL,const_cast<char*>(res.data()),MAX_PATH,arg.c_str(), arg.length());
return res;
}


// Convert string to wstring   
std::wstring str_to_wstr(const std::string& arg)
{
std::wstring res(arg.length(), L'\0');
mbstowcs_s(NULL,const_cast<wchar_t*>(res.data()),MAX_PATH ,arg.c_str(),arg.length());
return res;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////


void RTrim(tstring &str, const tstring& chars = _T(" \t"))
{
str.erase(str.find_last_not_of(chars)+1);
}


void LTrim(tstring &str, const tstring& chars =_T(" \t" ))
{
str.erase(0, str.find_first_not_of(chars));
}


void Trim( tstring& str , const tstring& chars =_T(" \t" ))
{
str.erase(str.find_last_not_of(chars)+1);
str.erase(0, str.find_first_not_of(chars));
}


CIniFile::CIniFile(const tstring& fileName)
{
m_strFileName = fileName;
Load(false);
}


CIniFile::~CIniFile()
{
Save();
RemoveAllSections( );
}


const wchar_t* const CIniFile::LF = _CRLFW;


void CIniFile::Save()
{
tstring sSection;
if (m_strFileName.empty())
{
assert(FALSE);
return;
}
tofstream output;
output.open(m_strFileName);
for( SecIndex::iterator itr = m_sections.begin() ; itr != m_sections.end() ; ++itr )
{
sSection = L"[" + (*itr)->GetSectionName() + L"]";


output << sSection << _CRLFA;


for( KeyIndex::iterator klitr = (*itr)->m_keys.begin() ; klitr !=  (*itr)->m_keys.end() ; ++klitr )
{
std::wstring sKey = (*klitr)->GetKeyName() + L"=" + (*klitr)->GetValue();
output << sKey << _CRLFA;
}
}
output.close();
}


void CIniFile::Load(bool bMerge )
{
if( !bMerge )
RemoveAllSections();
if (m_strFileName.empty())
{
assert(FALSE);
return;
}
tfstream input;
input.open(m_strFileName, std::ios::in|std::ios::app);
CIniSection* pSection = NULL;
tstring sRead;
enum { KEY , SECTION , COMMENT , OTHER };


while( std::getline( input , sRead ) )
{


// Trim all whitespace on the left
LTrim( sRead );
// Trim any returns
RTrim( sRead ,_T("\n\r"));


if( !sRead.empty() )
{
unsigned int nType = ( sRead.find_first_of(L"[") == 0 && ( sRead[sRead.find_last_not_of(L" \t\r\n")] == L']' ) ) ? SECTION : OTHER ;
nType = ( (nType == OTHER) && ( sRead.find_first_of(L"=") != tstring::npos && sRead.find_first_of(L"=") > 0 ) ) ? KEY : nType ;
nType = ( (nType == OTHER) && ( sRead.find_first_of(L"#") == 0) ) ? COMMENT : nType ;


switch( nType )
{
case SECTION:
pSection = AddSection( sRead.substr( 1 , sRead.size() - 2 ) );
break;


case KEY:
{
// Check to ensure valid section... or drop the keys listed
if( pSection )
{
size_t iFind = sRead.find_first_of(L"=");
tstring sKey = sRead.substr(0,iFind);
tstring sValue = sRead.substr(iFind + 1);
CIniKey* pKey = pSection->AddKey( sKey );
if( pKey )
{
pKey->SetValue( sValue );
}
}
}
break;
case COMMENT:
break;
case OTHER:
break;
}
}
}
input.close();
}




const SecIndex& CIniFile::GetSections() const
{
return m_sections;
}


CIniSection* CIniFile::GetSection( tstring sSection ) const
{
Trim(sSection);
SecIndex::const_iterator itr = _find_sec( sSection );
if( itr != m_sections.end() )
return *itr;
return NULL;
}


CIniSection* CIniFile::AddSection( tstring sSection )
{
Trim(sSection);
SecIndex::const_iterator itr = _find_sec( sSection );
if( itr == m_sections.end() )
{
// Note constuctor doesn't trim the string so it is trimmed above
CIniSection* pSection = new CIniSection( this , sSection );
m_sections.insert(pSection);
return pSection;
}
else
return *itr;
}




tstring CIniFile::GetKeyValue( const tstring& sSection, const tstring& sKey ) const
{
tstring sValue;
CIniSection* pSec = GetSection( sSection );
if( pSec )
{
CIniKey* pKey = pSec->GetKey( sKey );
if( pKey )
sValue = pKey->GetValue();
}
return sValue;
}


void CIniFile::SetKeyValue( const tstring& sSection, const tstring& sKey, const tstring& sValue )
{
CIniSection* pSec = AddSection( sSection );
if( pSec )
{
CIniKey* pKey = pSec->AddKey( sKey );
if( pKey )
pKey->SetValue( sValue );
}
}




void CIniFile::RemoveSection( std::wstring sSection )
{
Trim(sSection);
SecIndex::iterator itr = _find_sec( sSection );
if( itr != m_sections.end() )
{
delete *itr;
m_sections.erase( itr );
}
}


void CIniFile::RemoveSection( CIniSection* pSection )
{
// No trim since internal object not from user
SecIndex::iterator itr = _find_sec( pSection->m_sSectionName );
if( itr != m_sections.end() )
{
delete *itr;
m_sections.erase( itr );
}
}


void CIniFile::RemoveAllSections( )
{
for( SecIndex::iterator itr = m_sections.begin() ; itr != m_sections.end() ; ++itr )
{
delete *itr;
}
m_sections.clear();
}




bool CIniFile::RenameSection( const tstring& sSectionName  , const tstring& sNewSectionName )
{
// Note string trims are done in lower calls.
bool bRval = false;
CIniSection* pSec = GetSection( sSectionName );
if( pSec )
{
bRval = pSec->SetSectionName( sNewSectionName );
}
return bRval;
}


bool CIniFile::RenameKey( const tstring& sSectionName  , const tstring& sKeyName , const tstring& sNewKeyName)
{
// Note string trims are done in lower calls.
bool bRval = false;
CIniSection* pSec = GetSection( sSectionName );
if( pSec != NULL)
{
CIniKey* pKey = pSec->GetKey( sKeyName );
if( pKey != NULL )
bRval = pKey->SetKeyName( sNewKeyName );
}
return bRval;
}


// Returns a constant iterator to a section by name, string is not trimmed
SecIndex::const_iterator CIniFile::_find_sec( const tstring& sSection ) const
{
CIniSection bogus(NULL,sSection);
return m_sections.find( &bogus );
}


// Returns an iterator to a section by name, string is not trimmed
SecIndex::iterator CIniFile::_find_sec( const tstring& sSection )
{
CIniSection bogus(NULL,sSection);
return m_sections.find( &bogus );
}




//////////////////////////////////////////////////////////////////////////
// CIniSectionW functions start here   


CIniSection::CIniSection( CIniFile* pIniFile , const tstring& sSectionName ) : m_pIniFile(pIniFile) , m_sSectionName(sSectionName)
{


}




CIniSection::~CIniSection()
{
RemoveAllKeys();
}


CIniKey* CIniSection::GetKey( tstring sKeyName ) const
{
Trim(sKeyName);
KeyIndex::const_iterator itr = _find_key( sKeyName );
if( itr != m_keys.end() )
return *itr;
return NULL;
}


void CIniSection::RemoveAllKeys()
{
for( KeyIndex::iterator itr = m_keys.begin() ; itr != m_keys.end() ; ++itr )
{
delete *itr;
}
m_keys.clear();
}


void CIniSection::RemoveKey( tstring sKey )     
{
Trim( sKey );
KeyIndex::iterator itr = _find_key( sKey );
if( itr != m_keys.end() )
{
delete *itr;
m_keys.erase( itr );
}
}


void CIniSection::RemoveKey( CIniKey* pKey )
{
// No trim is done to improve efficiency since CIniKeyW* should already be trimmed
KeyIndex::iterator itr = _find_key( pKey->m_sKeyName );
if( itr != m_keys.end() )
{
delete *itr;
m_keys.erase( itr );
}
}


CIniKey* CIniSection::AddKey( tstring sKeyName )        
{
Trim(sKeyName);
KeyIndex::const_iterator itr = _find_key( sKeyName );
if( itr == m_keys.end() )
{
// Note constuctor doesn't trim the string so it is trimmed above
CIniKey* pKey = new CIniKey( this , sKeyName );
m_keys.insert(pKey);
return pKey;
}
else
return *itr;
}


bool CIniSection::SetSectionName( tstring sSectionName )
{
Trim(sSectionName);
// Does this already exist.
if( m_pIniFile->_find_sec( sSectionName ) == m_pIniFile->m_sections.end() )
{
// Find the current section if one exists and remove it since we are renaming
SecIndex::iterator itr = m_pIniFile->_find_sec( m_sSectionName );


// Just to be safe make sure the old section exists
if( itr != m_pIniFile->m_sections.end() )
m_pIniFile->m_sections.erase(itr);


// Change name prior to ensure tree balance
m_sSectionName = sSectionName;


// Set the new map entry we know should not exist
m_pIniFile->m_sections.insert(this);


return true;
}
else
{
return false;
}
}


tstring CIniSection::GetSectionName() const
{
return m_sSectionName;
}


const KeyIndex& CIniSection::GetKeys() const
{
return m_keys;
}


tstring CIniSection::GetKeyValue( tstring sKey ) const
{
tstring sValue;
CIniKey* pKey = GetKey( sKey );
if( pKey )
{
sValue = pKey->GetValue();
}
return sValue;
}


void CIniSection::SetKeyValue( tstring sKey, const tstring& sValue )
{
CIniKey* pKey = AddKey( sKey );
if( pKey )
{
pKey->SetValue( sValue );
}
}


// Returns a constant iterator to a key by name, string is not trimmed
KeyIndex::const_iterator CIniSection::_find_key( const tstring& sKey ) const
{
CIniKey bogus(NULL,sKey);
return m_keys.find( &bogus );
}


// Returns an iterator to a key by name, string is not trimmed
KeyIndex::iterator CIniSection::_find_key( const tstring& sKey )
{
CIniKey bogus(NULL,sKey);
return m_keys.find( &bogus );
}


#define INI  _T("Default")


bool  CIniFile::Writeini (LPCTSTR sSection,LPCTSTR sKeyName,LPCTSTR sValue ,LPCTSTR fileName)
{
if((sSection==NULL)||(_tcslen(sSection)==0))
{
sSection= INI;
}
if(sKeyName==NULL||(_tcslen(sKeyName)==0))
{
return false;
}


CIniSection* pSec = AddSection( sSection );
if (pSec)
{
pSec->AddKey(sKeyName);
pSec->AddKey(sKeyName)->SetValue(sValue);
}

return true;
}


tstring CIniFile::Readini(LPCTSTR sSection,LPCTSTR sKeyName, LPTSTR sValue , LPCTSTR  lpszDefaultValue,LPCTSTR fileName,  size_t cchValueMax)
{
if((sSection==NULL)||(wcslen(sSection)==0))
{
sSection=INI;
}
if((sKeyName==NULL)||(wcslen(sKeyName)==0))
{
return _T("");
}
if (sValue && cchValueMax)
{
memset(sValue, 0, cchValueMax*sizeof(TCHAR));
}

tstring strValue;
//如果为空或长度为0 ,则给他一个默认值,则就不用else语句了
CIniSection* pSection = GetSection(sSection );  
if( pSection )
{
CIniKey* pKey = pSection->GetKey(sKeyName); 
{
if(pKey)
{
strValue = pKey->GetValue();
}
}
}


if (strValue.empty())
{
if((lpszDefaultValue!=NULL)&&(_tcslen(lpszDefaultValue)!=0))
{
strValue = lpszDefaultValue;
}
}
if (sValue && !strValue.empty())
{
_tcsncpy_s(sValue, cchValueMax, strValue.c_str(), _TRUNCATE);
}
return strValue;
}


// CIniSectionW function end here  


//////////////////////////////////////////////////////////////////////////
// CIniKeyW Functions Start Here   


CIniKey::CIniKey( CIniSection* pSection , const tstring& sKeyName ) : m_pSection(pSection) , m_sKeyName(sKeyName)
{


}




CIniKey::~CIniKey()
{


}


void CIniKey::SetValue( const tstring& sValue )
{
m_sValue = sValue;
}


tstring CIniKey::GetValue() const
{
return m_sValue;
}


bool CIniKey::SetKeyName(tstring sKeyName )
{
Trim( sKeyName );


// Check for key name conflict
if( m_pSection->_find_key( sKeyName ) == m_pSection->m_keys.end() )
{
KeyIndex::iterator itr = m_pSection->_find_key( m_sKeyName );


// Find the old map entry and remove it
if( itr != m_pSection->m_keys.end() )
m_pSection->m_keys.erase( itr );


// Change name prior to ensure tree balance
m_sKeyName = sKeyName;


// Make the new map entry
m_pSection->m_keys.insert(this);
return true;
}
else
{
return false;
}
}


std::wstring CIniKey::GetKeyName() const
{
return m_sKeyName;
}


//////////////////////////////////////////////////////////////////////////
//CFileName
CFileName::CFileName()
{


}


CFileName::~CFileName()
{
RemoveAllFileNames();
}


CSaveFileName* CFileName:: GetFileName( tstring sFileName )
{
Trim(sFileName);
FileIndex::const_iterator itr = _find_file( sFileName );
if( itr==m_FileNames.end() )
{
CSaveFileName* pIniFile = new CSaveFileName(this , sFileName );
m_FileNames.insert(pIniFile);
return pIniFile;
}
else
return *itr;
}


void CFileName::RemoveAllFileNames( )
{
for( FileIndex::iterator itr = m_FileNames.begin() ; itr != m_FileNames.end() ; ++itr )
{
delete *itr;
}
m_FileNames.clear();
}


FileIndex::const_iterator CFileName::_find_file( const tstring& sFileName ) const
{
CSaveFileName bogus(NULL,sFileName);
return m_FileNames.find( &bogus );
}


FileIndex::iterator CFileName::_find_file( const tstring& sFileName )
{
CSaveFileName bogus(NULL,sFileName);
return m_FileNames.find( &bogus );
}
//////////////////////////////////////////////////////////////////////////
//CSaveFileName
CSaveFileName::CSaveFileName( CFileName* pFileName , const tstring& sFileName ):m_pFileName(pFileName) , m_sFileName(sFileName)
{
if (pFileName && !sFileName.empty())
{
m_pIniFile = new CIniFile(sFileName);
}
else
{
m_pIniFile = NULL;
}
}


CSaveFileName::~CSaveFileName()
{
if (m_pIniFile)
{
delete m_pIniFile;
m_pIniFile = NULL;
}
}

Profile.cpp



#include "stdafx.h"
#include "CoreMain.h"
#include "Core.h"
#include "Profile.h"
#include <SSNAPI.h> 




CProfile::CProfile(void)
{


}


CProfile::~CProfile(void)
{


}


VOID CProfile::Init()
{


}


VOID CProfile::UnInit()
{


}


INT CProfile::ReadProfileString(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue, __in size_t cchValueMax, __in_opt LPTSTR lpszDefaultValue)
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
tstring reValue;
reValue = pFileName->m_pIniFile->Readini(lpszSection,lpszKey,lpszValue, lpszDefaultValue,lpszIniFileName,cchValueMax);
return  reValue.length();
}


SSN_RETURN CProfile::WriteProfileString(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in LPCTSTR lpszValue)
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
BOOL ret =pFileName->m_pIniFile->Writeini(lpszSection,lpszKey,lpszValue,lpszIniFileName);
if(ret==TRUE)
{
return SSN_OK;
}else
{
return SSN_FALSE;
}
}


INT CProfile::ReadProfileBinary(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __inout BYTE* pData, __in UINT nBytes)
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
TCHAR szT[MAX_PATH];
tstring reValue;
reValue = pFileName->m_pIniFile->Readini(lpszSection,lpszKey,szT, NULL,lpszIniFileName,MAX_PATH);
if (szT == NULL)
return 0;
UINT ShouldBytes =reValue.length();
if(ShouldBytes>nBytes)
{
return ShouldBytes;
}else
{
return nBytes;
}
}


SSN_RETURN CProfile::WriteProfileBinary(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in BYTE* pData, __in UINT nBytes)
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
LPTSTR lpsz = new TCHAR[nBytes*2+1];
UINT i;
for (i = 0; i < nBytes; i++)
{
lpsz[i*2] = (TCHAR)((pData[i] & 0x0F) + 'A');          //低字节
lpsz[i*2+1] = (TCHAR)(((pData[i] >> 4) & 0x0F) + 'A'); //高字节
}
lpsz[i*2] = 0;
BOOL ret = pFileName->m_pIniFile->Writeini(lpszSection,lpszKey,lpsz,lpszIniFileName);
if(ret==TRUE)
{
delete [] lpsz;
return SSN_OK;
}else
{
delete [] lpsz;
return SSN_FALSE;
}
}


INT CProfile::ReadProfileInt(__in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in_opt INT nDefault)
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
TCHAR szT[MAX_PATH];
TCHAR sDefault[MAX_PATH];
_stprintf_s(sDefault, _countof(szT), _T("%d"), nDefault);
tstring  retValue ;
retValue =pFileName->m_pIniFile->Readini( lpszSection,lpszKey,szT,sDefault,lpszIniFileName,MAX_PATH);
INT nretValue=0;
nretValue= _ttoi(retValue.c_str());
return nretValue;
}


SSN_RETURN CProfile::WriteProfileInt( __in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in INT nValue )
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
TCHAR szT[MAX_PATH];
_stprintf_s(szT, _countof(szT), _T("%d"), nValue);
BOOL ret =pFileName->m_pIniFile->Writeini(lpszSection, lpszKey, szT,lpszIniFileName);
if(ret==TRUE)
{
return SSN_OK;
}else
{
return SSN_FALSE;
}
return SSN_FALSE;
}


DOUBLE CProfile::ReadProfileDouble( __in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in_opt DOUBLE dDefault )
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
TCHAR szT[MAX_PATH];
tstring reValue;
reValue = pFileName->m_pIniFile->Readini( lpszSection,lpszKey,szT,NULL,lpszIniFileName,MAX_PATH);
return (reValue.c_str()!= NULL) ? _tstof(reValue.c_str()) : dDefault;
}


SSN_RETURN CProfile::WriteProfileDouble( __in LPCTSTR lpszIniFileName, __in_opt LPCTSTR lpszSection, __in LPCTSTR lpszKey, __in DOUBLE dValue )
{
CSaveFileName* pFileName=m_FileName.GetFileName(lpszIniFileName);
TCHAR szT[MAX_PATH];
_stprintf_s(szT, _countof(szT), _T("%f"), dValue);
BOOL ret =pFileName->m_pIniFile->Writeini(lpszSection, lpszKey,szT,lpszIniFileName);
if (ret == TRUE )
return SSN_OK;
else
return SSN_FALSE; 
}

方法二:Profile用端口API函数写的读写ini文件

#include "stdafx.h"
#define SSNAPI_EXPORTS
#include "CoreMain.h"
#include "Core.h"
#include "Profile.h"
#include <SSNAPI.h> 
#include <atlstr.h>
#include <iostream>
#include <assert.h>
#include <stdlib.h> 
#include <stdio.h> 
using   namespace   std; 


//////////////////////////////////////////////////////////////////////
class   RWini
{
public:
RWini();
~RWini();
CORE_API INT DoSsnReadProfileString( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue, __in size_t cchValueMax, __in_opt LPTSTR lpszDefaultValue );
CORE_API SSN_RETURN DoSsnWriteProfileString( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in LPTSTR lpszValue );
int insert(__in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue);
public:
INT  nPlugInId[MAX_PATH];
TCHAR lGName[MAX_PATH];
TCHAR lKName[MAX_PATH];
TCHAR lpszValue[MAX_PATH];
INT nCount;
};
 RWini::RWini()
{
INT nCount = 0;
}


int RWini::insert(__in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue)
{
if (nCount<MAX_PATH)
{
nPlugInId[nCount]=nPlugInId;
lGName[nCount] =lpszGroupName;    //tstring lGName = lpszGroupName;
lKName[nCount]=lpszKey;
lpszValue[nCount]=lpszValue;
nCount++;
}
}


CORE_API INT DoSsnReadProfileString( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __out_ecount(cchValueMax) LPTSTR lpszValue, __in size_t cchValueMax, __in_opt LPTSTR lpszDefaultValue )
{


TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
TCHAR szT[MAX_PATH];
GetPrivateProfileString(lpszGroupName, lpszKey,lpszDefaultValue, szT, cchValueMax, szPath);
//lpszGroupName 节名
//lpszKey 键名 
//lpszDefaultValue 为空时的默认值 
//szT 存放键值的指针变量,用于接收INI文件中键值(数据)的接收缓冲区
//cchValueMax lpReturnedString的缓冲区大小
//filename INI文件的路径
unsigned int retValueLength=_tcslen(szT);
if(cchValueMax < retValueLength)
return retValueLength;
else 
return cchValueMax;
}


CORE_API SSN_RETURN DoSsnWriteProfileString( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in LPTSTR lpszValue )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
//存放的路径用nPlugInId来标识,如存放文件为A_nPlugInId.ini
BOOL ret =WritePrivateProfileString(lpszGroupName,lpszKey,lpszValue,szPath);
//lpszGroupName    节名
//lpszKey          键名
//lpszValue        键值,也就是数据
//filename         INI文件的路径
if(ret==TRUE){
return SSN_OK;
}else{
return SSN_FALSE;
}
}


CORE_API INT DoSsnReadProfileBinary( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __out BYTE* pData, __in UINT nBytes )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
TCHAR szT[MAX_PATH];
GetPrivateProfileString(lpszGroupName, lpszKey, NULL, szT, MAX_PATH, szPath);
if (szT == NULL)
return 0;
UINT ShouldBytes = _tcslen(szT);
if(ShouldBytes>nBytes){
return ShouldBytes;
}else{
return nBytes;
}
}


CORE_API SSN_RETURN DoSsnWriteProfileBinary( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in BYTE* pData, __in UINT nBytes )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
// 二进制转换为字符串,并写出
LPTSTR lpsz = new TCHAR[nBytes*2+1];
UINT i;
for (i = 0; i < nBytes; i++)
{
lpsz[i*2] = (TCHAR)((pData[i] & 0x0F) + 'A');          //低字节
lpsz[i*2+1] = (TCHAR)(((pData[i] >> 4) & 0x0F) + 'A'); //高字节
}
lpsz[i*2] = 0;
BOOL ret =WritePrivateProfileString(lpszGroupName,lpszKey,lpsz,szPath);
if(ret==TRUE){
delete [] lpsz;
return SSN_OK;
}else{
delete [] lpsz;
return SSN_FALSE;
}
}


CORE_API INT DoSsnReadProfileInt( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in_opt INT nDefault )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
INT retValueLength = 0;
retValueLength = GetPrivateProfileInt(lpszGroupName,lpszKey,nDefault,szPath);
//lpszGroupName       节名
//lpszKey             键名
//nDefault            如果没有找到指定的数据返回,则把个变量值赋给返回值
//nPath               INI文件的路径
//读取整形值:(返回值为读到的整数)
return retValueLength;
}


CORE_API SSN_RETURN DoSsnWriteProfileInt( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in INT nValue )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
TCHAR szT[MAX_PATH];
_stprintf_s(szT, _countof(szT), _T("%d"), nValue);
BOOL ret =WritePrivateProfileString(lpszGroupName, lpszKey, szT,szPath);
if(ret==TRUE){
return SSN_OK;
}else{
return SSN_FALSE;
}
}


CORE_API DOUBLE DoSsnReadProfileDouble( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in_opt DOUBLE dDefault )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
TCHAR d[MAX_PATH];
GetPrivateProfileString(lpszGroupName, lpszKey, NULL, d, 128, szPath);
return (d[0] != 0) ? _wtof(d) : dDefault;
}


CORE_API SSN_RETURN DoSsnWriteProfileDouble( __in INT nPlugInId, __in_opt LPTSTR lpszGroupName, __in LPTSTR lpszKey, __in DOUBLE dValue )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_CONFIG, szPath, MAX_PATH, nPlugInId, NULL);
char szT[MAX_PATH];
int digits=100;
_gcvt_s(szT,MAX_PATH,dValue,digits);
BOOL ret =WritePrivateProfileString(lpszGroupName,lpszKey,SSN::CA2W(szT),szPath);
//lpszGroupName    节名
//lpszKey          键名
//szT              键值,也就是数据
//nPath            INI文件的路径
if (ret == TRUE )
return SSN_OK;
else
return SSN_FALSE; 
}


//TODO: 还没实现,临时拷贝default


CORE_API INT DoSsnGetLocaleString( __in INT nPlugInId, __in_opt INT nLocaleId, __in_opt LPCTSTR szGroupName, __in LPCTSTR szStringId, __out_ecount(cchStringMax) LPTSTR szString, __in size_t cchStringMax, __in LPCTSTR szDefaultString )
{
TCHAR szPath[MAX_PATH] = {0};
DoSsnGetPath(SSN_PATH_LOCALE, szPath, MAX_PATH, nPlugInId, nLocaleId);
GetPrivateProfileString(szGroupName, szStringId,szDefaultString, szString, cchStringMax, szPath);
if (0 == _tcscpy_s(szString, cchStringMax, szDefaultString))
{
return _tcslen(szString);
}
else
{
return 0;
}
}



原创粉丝点击