您的位置:首页 > 编程语言 > C语言/C++

c语言读写配置文件

2014-05-15 11:35 465 查看
/************************************************************************
T h e   O p e n   W i n d o w s   P r o j e c t
------------------------------------------------------------------------
Filename   : IniFile.h
Author(s)  : Carsten Breuer
------------------------------------------------------------------------
Copyright (c) 2000 by Carsten Breuer (C.Breuer@openwin.de)
/************************************************************************/

#ifndef INIFILE_H
#define INIFILE_H

#ifdef LINUX /* Remove CR, on unix systems. */
#define INI_REMOVE_CR
#define DONT_HAVE_STRUPR
#endif

#ifndef CCHR_H
#define CCHR_H
typedef const char cchr;
#endif

#ifndef __cplusplus
typedef char bool;
#define true  1
#define TRUE  1
#define false 0
#define FALSE 0
#endif

#define tpNULL       0
#define tpSECTION    1
#define tpKEYVALUE   2
#define tpCOMMENT    3

struct ENTRY
{
char   Type;
char  *Text;
struct ENTRY *pPrev;
struct ENTRY *pNext;
} ENTRY;

typedef struct
{
struct ENTRY *pSec;
struct ENTRY *pKey;
char          KeyText [128];
char          ValText [128];
char          Comment [255];
} EFIND;

/* Macros */
#define ArePtrValid(Sec,Key,Val) ((Sec!=NULL)&&(Key!=NULL)&&(Val!=NULL))

/* Connectors of this file (Prototypes) */

bool    OpenIniFile (cchr *FileName);

bool    ReadBool    (cchr *Section, cchr *Key, bool   Default);
int     ReadInt     (cchr *Section, cchr *Key, int    Default);
double  ReadDouble  (cchr *Section, cchr *Key, double Default);
cchr   *ReadString  (cchr *Section, cchr *Key, cchr  *Default);

void    WriteBool   (cchr *Section, cchr *Key, bool   Value);
void    WriteInt    (cchr *Section, cchr *Key, int    Value);
void    WriteDouble (cchr *Section, cchr *Key, double Value);
void    WriteString (cchr *Section, cchr *Key, cchr  *Value);

bool	DeleteKey (cchr *Section, cchr *Key);

void    CloseIniFile ();
bool    WriteIniFile (cchr *FileName);

#endif
/************************************************************************
Filename   : IniFile.C
Version    : 0.51
Author(s)  : Carsten Breuer
--[ Description ]-------------------------------------------------------

This file contains a complete interface to read and write ini files
like windows do it. It's also avaiable as a C++ class.

--[ History ] ----------------------------------------------------------

0.10: Original file by Carsten Breuer. First beta version.
0.20: Some bugs resolved and some suggestions from
jim hall (freedos.org) implemented.
0.30: Some stuff for unix added. They dont know strupr.
Thanks to Dieter Engelbrecht (dieter@wintop.net).
0.40: Bug at WriteString fixed.
0.50: Problem with file pointer solved
0.51: We better do smaller steps now. I have reformated to tab4. Sorry
New function DeletepKey added. Thanks for the guy who post this.

--[ How to compile ]----------------------------------------------------

This file was developed under DJGPP and Rhide. If you are familiar with
Borland C++ 3.1, you will feel like at home ;-)).
Both tools are free software.

Downloads at: http://www.delorie.com/djgpp 
--[ Where to get help/information ]-------------------------------------

The author   : C.Breuer@OpenWin.de

--[ License ] ----------------------------------------------------------

LGPL (Free for private and comercial use)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

------------------------------------------------------------------------
Copyright (c) 2000 Carsten Breuer
/************************************************************************/

/* defines for, or consts and inline functions for C++ */

/* global includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>	/* Only needed for the test function */

#define FALSE 0
#define TRUE 1

/* local includes */
#include "readIni.h"

/* Global Variables */

struct ENTRY *Entry = NULL;
struct ENTRY *CurEntry = NULL;
char Result[255] =
{""};
FILE *IniFile;

/* Private functions declarations */
void AddpKey (struct ENTRY *Entry, cchr * pKey, cchr * Value);
void FreeMem (void *Ptr);
void FreeAllMem (void);
bool FindpKey (cchr * Section, cchr * pKey, EFIND * List);
bool AddSectionAndpKey (cchr * Section, cchr * pKey, cchr * Value);
struct ENTRY *MakeNewEntry (void);

/*=========================================================================
strupr -de-
-------------------------------------------------------------------------
Job : String to Uppercase 22.03.2001 Dieter Engelbrecht dieter@wintop.net
/*========================================================================*/
#ifdef DONT_HAVE_STRUPR
/* DONT_HAVE_STRUPR is set when INI_REMOVE_CR is defined */
void strupr( char *str )
{
// We dont check the ptr because the original also dont do it.
while (*str != 0)
{
if ( islower( *str ) )
{
*str = toupper( *str );
}
str++;
}
}
#endif

/*=========================================================================
OpenIniFile
-------------------------------------------------------------------------
Job : Opens an ini file or creates a new one if the requested file
doesnt exists.

Att : Be sure to call CloseIniFile to free all mem allocated during
operation!
/*========================================================================*/
bool
OpenIniFile (cchr * FileName)
{
char Str[255];
char *pStr;
struct ENTRY *pEntry;

FreeAllMem ();

if (FileName == NULL)
{
return FALSE;
}
if ((IniFile = fopen (FileName, "r")) == NULL)
{
return FALSE;
}

while (fgets (Str, 255, IniFile) != NULL)
{
pStr = strchr (Str, '\n');
if (pStr != NULL)
{
*pStr = 0;
}
pEntry = MakeNewEntry ();
if (pEntry == NULL)
{
return FALSE;
}

#ifdef INI_REMOVE_CR
Len = strlen(Str);
if ( Len > 0 )
{
if ( Str[Len-1] == '\r' )
{
Str[Len-1] = '\0';
}
}
#endif

pEntry->Text = (char *) malloc (strlen (Str) + 1);
if (pEntry->Text == NULL)
{
FreeAllMem ();
return FALSE;
}
strcpy (pEntry->Text, Str);
pStr = strchr (Str, ';');
if (pStr != NULL)
{
*pStr = 0;
}			/* Cut all comments */
if ((strstr (Str, "[") > 0) && (strstr (Str, "]") > 0))	/* Is Section */
{
pEntry->Type = tpSECTION;
}
else
{
if (strstr (Str, "=") > 0)
{
pEntry->Type = tpKEYVALUE;
}
else
{
pEntry->Type = tpCOMMENT;
}
}
CurEntry = pEntry;
}
fclose (IniFile);
IniFile = NULL;
return TRUE;
}

/*=========================================================================
CloseIniFile
-------------------------------------------------------------------------
Job : Frees the memory and closes the ini file without any
modifications. If you want to write the file use
WriteIniFile instead.
/*========================================================================*/
void
CloseIniFile (void)
{
FreeAllMem ();
if (IniFile != NULL)
{
fclose (IniFile);
IniFile = NULL;
}
}

/*=========================================================================
WriteIniFile
-------------------------------------------------------------------------
Job : Writes the iniFile to the disk and close it. Frees all memory
allocated by WriteIniFile;
/*========================================================================*/
bool
WriteIniFile (const char *FileName)
{
struct ENTRY *pEntry = Entry;
IniFile = NULL;
if (IniFile != NULL)
{
fclose (IniFile);
}
if ((IniFile = fopen (FileName, "wb")) == NULL)
{
FreeAllMem ();
return FALSE;
}

while (pEntry != NULL)
{
if (pEntry->Type != tpNULL)
{

#ifdef INI_REMOVE_CR
fprintf (IniFile, "%s\n", pEntry->Text);
#else
fprintf (IniFile, "%s\r\n", pEntry->Text);
#endif
pEntry = pEntry->pNext;
}
}

fclose (IniFile);
IniFile = NULL;
return TRUE;
}

/*=========================================================================
WriteString : Writes a string to the ini file
*========================================================================*/
void
WriteString (cchr * Section, cchr * pKey, cchr * Value)
{
EFIND List;
char Str[255];

if (ArePtrValid (Section, pKey, Value) == FALSE)
{
return;
}
if (FindpKey (Section, pKey, &List) == TRUE)
{
sprintf (Str, "%s=%s%s", List.KeyText, Value, List.Comment);
FreeMem (List.pKey->Text);
List.pKey->Text = (char *) malloc (strlen (Str) + 1);
strcpy (List.pKey->Text, Str);
}
else
{
if ((List.pSec != NULL) && (List.pKey == NULL))	/* section exist, pKey not */
{
AddpKey (List.pSec, pKey, Value);
}
else
{
AddSectionAndpKey (Section, pKey, Value);
}
}
}

/*=========================================================================
WriteBool : Writes a boolean to the ini file
*========================================================================*/
void
WriteBool (cchr * Section, cchr * pKey, bool Value)
{
char Val[2] = {'0', 0};
if (Value != 0)
{
Val[0] = '1';
}
WriteString (Section, pKey, Val);
}

/*=========================================================================
WriteInt : Writes an integer to the ini file
*========================================================================*/
void
WriteInt (cchr * Section, cchr * pKey, int Value)
{
char Val[12];			/* 32bit maximum + sign + \0 */
sprintf (Val, "%d", Value);
WriteString (Section, pKey, Val);
}

/*=========================================================================
WriteDouble : Writes a double to the ini file
*========================================================================*/
void
WriteDouble (cchr * Section, cchr * pKey, double Value)
{
char Val[32];			/* DDDDDDDDDDDDDDD+E308\0 */
sprintf (Val, "%1.10lE", Value);
WriteString (Section, pKey, Val);
}

/*=========================================================================
ReadString : Reads a string from the ini file
*========================================================================*/
const char *
ReadString (cchr * Section, cchr * pKey, cchr * Default)
{
EFIND List;
if (ArePtrValid (Section, pKey, Default) == FALSE)
{
return Default;
}
if (FindpKey (Section, pKey, &List) == TRUE)
{
strcpy (Result, List.ValText);
return Result;
}
return Default;
}

/*=========================================================================
ReadBool : Reads a boolean from the ini file
*========================================================================*/
bool
ReadBool (cchr * Section, cchr * pKey, bool Default)
{
char Val[2] = {"0"};
if (Default != 0)
{
Val[0] = '1';
}
return (atoi (ReadString (Section, pKey, Val)) ? 1 : 0);	/* Only 0 or 1 allowed */
}

/*=========================================================================
ReadInt : Reads a integer from the ini file
*========================================================================*/
int
ReadInt (cchr * Section, cchr * pKey, int Default)
{
char Val[12];
sprintf (Val, "%d", Default);
return (atoi (ReadString (Section, pKey, Val)));
}

/*=========================================================================
ReadDouble : Reads a double from the ini file
*========================================================================*/
double
ReadDouble (cchr * Section, cchr * pKey, double Default)
{
double Val;
sprintf (Result, "%1.10lE", Default);
sscanf (ReadString (Section, pKey, Result), "%lE", &Val);
return Val;
}

/*=========================================================================
DeleteKey : Deletes a pKey from the ini file.
*========================================================================*/

bool DeleteKey (cchr *Section, cchr *pKey)
{
EFIND         List;
struct ENTRY *pPrev;
struct ENTRY *pNext;

if (FindpKey (Section, pKey, &List) == TRUE)
{
pPrev = List.pKey->pPrev;
pNext = List.pKey->pNext;
if (pPrev)
{
pPrev->pNext=pNext;
}
if (pNext)
{
pNext->pPrev=pPrev;
}
FreeMem (List.pKey->Text);
FreeMem (List.pKey);
return TRUE;
}
return FALSE;
}

/* Here we start with our helper functions */
/*=========================================================================
FreeMem : Frees a pointer. It is set to NULL by Free AllMem
*========================================================================*/
void
FreeMem (void *Ptr)
{
if (Ptr != NULL)
{
free (Ptr);
}
}

/*=========================================================================
FreeAllMem : Frees all allocated memory and set the pointer to NULL.
Thats IMO one of the most important issues relating
to pointers :

A pointer is valid or NULL.
*========================================================================*/
void
FreeAllMem (void)
{
struct ENTRY *pEntry;
struct ENTRY *pNextEntry;
pEntry = Entry;
while (1)
{
if (pEntry == NULL)
{
break;
}
pNextEntry = pEntry->pNext;
FreeMem (pEntry->Text);	/* Frees the pointer if not NULL */
FreeMem (pEntry);
pEntry = pNextEntry;
}
Entry = NULL;
CurEntry = NULL;
}

/*=========================================================================
FindSection : Searches the chained list for a section. The section
must be given without the brackets!
Return Value: NULL at an error or a pointer to the ENTRY structure
if succeed.
*========================================================================*/
struct ENTRY *
FindSection (cchr * Section)
{
char Sec[130];
char iSec[130];
struct ENTRY *pEntry;
sprintf (Sec, "[%s]", Section);
strupr (Sec);
pEntry = Entry;		/* Get a pointer to the first Entry */
while (pEntry != NULL)
{
if (pEntry->Type == tpSECTION)
{
strcpy (iSec, pEntry->Text);
strupr (iSec);
if (strcmp (Sec, iSec) == 0)
{
return pEntry;
}
}
pEntry = pEntry->pNext;
}
return NULL;
}

/*=========================================================================
FindpKey     : Searches the chained list for a pKey under a given section
Return Value: NULL at an error or a pointer to the ENTRY structure
if succeed.
*========================================================================*/
bool
FindpKey (cchr * Section, cchr * pKey, EFIND * List)
{
char Search[130];
char Found[130];
char Text[255];
char *pText;
struct ENTRY *pEntry;
List->pSec = NULL;
List->pKey = NULL;
pEntry = FindSection (Section);
if (pEntry == NULL)
{
return FALSE;
}
List->pSec = pEntry;
List->KeyText[0] = 0;
List->ValText[0] = 0;
List->Comment[0] = 0;
pEntry = pEntry->pNext;
if (pEntry == NULL)
{
return FALSE;
}
sprintf (Search, "%s", pKey);
strupr (Search);
while (pEntry != NULL)
{
if ((pEntry->Type == tpSECTION) ||	/* Stop after next section or EOF */
(pEntry->Type == tpNULL))
{
return FALSE;
}
if (pEntry->Type == tpKEYVALUE)
{
strcpy (Text, pEntry->Text);
pText = strchr (Text, ';');
if (pText != NULL)
{
strcpy (List->Comment, Text);
*pText = 0;
}
pText = strchr (Text, '=');
if (pText != NULL)
{
*pText = 0;
strcpy (List->KeyText, Text);
strcpy (Found, Text);
*pText = '=';
strupr (Found);
/* printf ("%s,%s\n", Search, Found); */
if (strcmp (Found, Search) == 0)
{
strcpy (List->ValText, pText + 1);
List->pKey = pEntry;
return TRUE;
}
}
}
pEntry = pEntry->pNext;
}
return FALSE;
}

/*=========================================================================
AddItem  : Adds an item (pKey or section) to the chaines list
*========================================================================*/
bool
AddItem (char Type, cchr * Text)
{
struct ENTRY *pEntry = MakeNewEntry ();
if (pEntry == NULL)
{
return FALSE;
}
pEntry->Type = Type;
pEntry->Text = (char *) malloc (strlen (Text) + 1);
if (pEntry->Text == NULL)
{
free (pEntry);
return FALSE;
}
strcpy (pEntry->Text, Text);
pEntry->pNext = NULL;
if (CurEntry != NULL)
{
CurEntry->pNext = pEntry;
}
CurEntry = pEntry;
return TRUE;
}

/*=========================================================================
AddItemAt : Adds an item at a selected position. This means, that the
chained list will be broken at the selected position and
that the new item will be Inserted.
Before : A.Next = &B
After  : A.Next = &NewItem, NewItem.Next = &B
*========================================================================*/
bool
AddItemAt (struct ENTRY * EntryAt, char Mode, cchr * Text)
{
struct ENTRY *pNewEntry;
if (EntryAt == NULL)
{
return FALSE;
}
pNewEntry = (struct ENTRY *) malloc (sizeof (ENTRY));
if (pNewEntry == NULL)
{
return FALSE;
}
pNewEntry->Text = (char *) malloc (strlen (Text) + 1);
if (pNewEntry->Text == NULL)
{
free (pNewEntry);
return FALSE;
}
strcpy (pNewEntry->Text, Text);
if (EntryAt->pNext == NULL)	/* No following nodes. */
{
EntryAt->pNext = pNewEntry;
pNewEntry->pNext = NULL;
}
else
{
pNewEntry->pNext = EntryAt->pNext;
EntryAt->pNext = pNewEntry;
}
pNewEntry->pPrev = EntryAt;
pNewEntry->Type = Mode;
return TRUE;
}

/*=========================================================================
AddSectionAndpKey  : Adds a section and then a pKey to the chained list
*========================================================================*/
bool
AddSectionAndpKey (cchr * Section, cchr * pKey, cchr * Value)
{
char Text[255];
sprintf (Text, "[%s]", Section);
if (AddItem (tpSECTION, Text) == FALSE)
{
return FALSE;
}
sprintf (Text, "%s=%s", pKey, Value);
return AddItem (tpKEYVALUE, Text);
}

/*=========================================================================
AddpKey  : Adds a pKey to the chained list
*========================================================================*/
void
AddpKey (struct ENTRY *SecEntry, cchr * pKey, cchr * Value)
{
char Text[255];
sprintf (Text, "%s=%s", pKey, Value);
AddItemAt (SecEntry, tpKEYVALUE, Text);
}

/*=========================================================================
MakeNewEntry  : Allocates the memory for a new entry. This is only
the new empty structure, that must be filled from
function like AddItem etc.
Info          : This is only a internal function. You dont have to call
it from outside.
*==========================================================================*/
struct ENTRY *
MakeNewEntry (void)
{
struct ENTRY *pEntry;
pEntry = (struct ENTRY *) malloc (sizeof (ENTRY));
if (pEntry == NULL)
{
FreeAllMem ();
return NULL;
}
if (Entry == NULL)
{
Entry = pEntry;
}
pEntry->Type = tpNULL;
pEntry->pPrev = CurEntry;
pEntry->pNext = NULL;
pEntry->Text = NULL;
if (CurEntry != NULL)
{
CurEntry->pNext = pEntry;
}
return pEntry;
}

#define INIFILE_TEST_THIS_FILE
#ifdef INIFILE_TEST_THIS_FILE
//#define INIFILE_TEST_READ_AND_WRITE
int main (void)
{
printf ("Hello World\n");
OpenIniFile ("Test.Ini");
#ifdef INIFILE_TEST_READ_AND_WRITE
WriteString  ("Test", "Name", "Value");
WriteString  ("Test", "Name", "OverWrittenValue");
WriteString  ("Test", "Port", "COM1");
WriteString  ("Test", "User", "James Brown jr.");
WriteString  ("Configuration", "eDriver", "MBM2.VXD");
WriteString  ("Configuration", "Wrap", "LPT.VXD");
WriteInt 	 ("IO-Port", "Com", 2);
WriteBool 	 ("IO-Port", "IsValid", 0);
WriteDouble  ("TheMoney", "TheMoney", 67892.00241);
WriteInt     ("Test"    , "ToDelete", 1234);
WriteIniFile ("Test.Ini");
printf ("Key ToDelete created. Check ini file. Any key to continue");
while (!kbhit());
OpenIniFile  ("Test.Ini");
DeleteKey    ("Test"	  , "ToDelete");
WriteIniFile ("Test.Ini");
#endif
printf ("[Test] Name = %s\n", ReadString ("Test", "Name", "NotFound"));
printf ("[Test] Port = %s\n", ReadString ("Test", "Port", "NotFound"));
printf ("[Test] User = %s\n", ReadString ("Test", "User", "NotFound"));
printf ("[Configuration] eDriver = %s\n", ReadString ("Configuration", "eDriver", "NotFound"));
printf ("[Configuration] Wrap = %s\n", ReadString ("Configuration", "Wrap", "NotFound"));
printf ("[IO-Port] Com = %d\n", ReadInt ("IO-Port", "Com", 0));
printf ("[IO-Port] IsValid = %d\n", ReadBool ("IO-Port", "IsValid", 0));
printf ("[TheMoney] TheMoney = %1.10lf\n", ReadDouble ("TheMoney", "TheMoney", 111));
CloseIniFile ();
return 0;
}
#endif


测试文件Test.ini

[Test]
User=James Brown jr.
Port=COM1
Name=OverWrittenValue
[Configuration]
Wrap=LPT.VXD
eDriver=MBM2.VXD
[IO-Port]
#是否有效
IsValid =0
Com=2

[TheMoney]
TheMoney=6.7892002410E+004
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: