During project development, you often need to read the initialization parameters of the application configuration file and perform initialization settings before the application starts. For example, in Eclipse, the parameter items include the subject, font size, color, Jdk installation location, and automatic prompt. The file format configured by Eclispe is stored as a key-value pair, that is, the key = value format. The following are some Eclipse settings parameters:
/instance/org.eclipse.jdt.ui/useQuickDiffPrefPage=true/instance/org.eclipse.jdt.ui/content_assist_proposals_foreground=0,0,0/instance/org.eclipse.egit.core/GitRepositoriesView.GitDirectories=/Users/yangxin/Downloads/kakaolink-android/.git\:/Users/yangxin/Documents/workspace_web/tfyj/.git\:/instance/org.eclipse.wst.jsdt.ui/fontPropagated=true/instance/org.eclipse.debug.core/org.eclipse.debug.core.USE_STEP_FILTERS=true/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.assertIdentifier=error/instance/org.eclipse.ui.workbench/org.eclipse.jface.textfont=1|Monaco|14.0|0|COCOA|1|Monaco;@org.eclipse.jdt.ui=3.8.2.v20130107-165834/instance/org.eclipse.cdt.ui/spelling_locale_initialized=true
From the Eclipse configuration file, we can see that
Xxxx = xxxxx
,For example, in the last configuration item, the key is/instance/org. eclipse. cdt. ui/spelling_locale_initialized. The value is true. This method is also often used in project development. I have designed a C configuration file read/write Interface Based on Java. util. Properties class.
1. Define the interface header file (Properties. h)
/// Properties. h // read/write configuration file /// Created by Yang Xin on 14-4-24. // Copyright (c) 2014 yangxin. all rights reserved. // # ifndef _______ Properties_h # define _______ Properties_h # ifdef _ cplusplusextern "C" {# endif // when the environment is initialized, 0 is returned, failed return non-0 value int init (const char * filepath, void ** handle); // obtain the value based on the KEY and return 0, if no value is found, int getValue (void * handle, const char * key, char * value) is returned. // if the value of the key is modified successfully, 0 is returned, failed return non-0 value int setValue (void * handle, const char * key, const char * value); // Add an attribute and return 0 if the attribute is added successfully, failed return non-0 value int add (void * handle, const char * key, const char * value); // delete an attribute, success return 0, failed return non-0 value int del (void * handle, const char * key); // get all the keys in the attribute file, get successful return 0, failed return non-0 value int getKeys (void * handle, char *** keys, int * keyscount); // release the memory space of all keys, success return 0, failed to return non-0 value int free_keys (char *** keys, int * keyscount); // get all values in the attribute file, success returns 0, failed return non-0 value int getValues (void * handle, char *** values, int * valuescount); // release the memory space of all values, success return 0, failed return non-0 value int free_values (char *** values, int * valuescount); // get the number of attributes, success return 0, non-0 int getCount (void * handle, int * count) is returned for failure; // environment resource is released. 0 is returned for success, return non-0 int release (void ** handle); # ifdef _ cplusplus} # endif
2. Implement the header file interface (Properteis. c)
/// Properties. c // read/write configuration file /// Created by Yang Xin on 14-4-24. // Copyright (c) 2014 yangxin. all rights reserved. // # include
# Include
# Include
# Include "Properties. h "# define KEY_SIZE 128 // key buffer size # define VALUE_SIZE 128 // value buffer size # define LINE_BUF_SIZE 256 // read the buffer size of each row in the configuration file typedef struct Properties {char * key; char * value; struct Properties * pNext;} Properties; typedef struct PROPS_HANDLE {Properties * pHead; // char * filepath; // attribute file path} PROPS_HANDLE; static int createPropsNode (Properties ** props); // create a node static int trimeSpac E (const char * src, char * dest); // remove space static int saveConfig (const char * filepath, Properties * head ); // Save the modified or saved configuration item to the file // initialization environment. If the initialization environment is successful, 0 is returned, and non-0 int init (const char * filepath, void ** handle) is returned) {int ret = 0; FILE * fp = NULL; Properties * pHead = NULL, * pCurrent = NULL, * pMalloc = NULL; PROPS_HANDLE * ph = NULL; char line [LINE_BUF_SIZE]; // store the char keybuff [KEY_SIZE] = {0} buffer for reading each row; // The char valuebuf buffer for storing the key F [VALUE_SIZE] = {0}; // The buffer that stores the value char * pLine = NULL; // if (filepath = NULL | handle = NULL) {ret =-1; printf ("fun init error: % d from (filepath = NULL | handler = NULL) \ n ", ret); return ret;} ph = (PROPS_HANDLE *) malloc (sizeof (PROPS_HANDLE )); if (ph = NULL) {ret =-2; printf ("fun init malloc handle error: % d", ret); return ret;} memset (ph, 0, sizeof (PROPS_HANDLE); // open the file Fp = fopen (filepath, "r"); if (! Fp) {ret =-3; printf ("fun init open file error: % d from % s \ n", ret, filepath); return ret ;} // create the header node ret = createPropsNode (& pHead); if (ret! = 0) {fclose (fp); // close the file printf ("fun init create head node error: % d \ n", ret); return ret;} memset (pHead, 0, sizeof (Properties); // Save the head node of the linked list and the file path to the handle. ph-> pHead = pHead; ph-> filepath = (char *) malloc (strlen (filepath) + 1); strcpy (ph-> filepath, filepath); pCurrent = pHead; // read all data in the configuration file while (! Feof (fp) {if (fgets (line, LINE_BUF_SIZE, fp) = NULL) {break;} // find the equal sign if (pLine = strstr (line, "=") = NULL) {// no equal sign, continue reading the next row of continue;} // create a node in a loop ret = createPropsNode (& pMalloc); if (ret! = 0) {fclose (fp); // close the file release (void **) & ph); // failed to create the node, release all resources printf ("create new node error: % d \ n", ret); return ret;} // set Key memcpy (keybuff, line, pLine-line ); trimeSpace (keybuff, pMalloc-> key); // place the keybuff with a space and put it in pMallock. in key, // set Value pLine + = 1; trimeSpace (pLine, valuebuff); strcpy (pMalloc-> value, valuebuff ); // Add the new node to the linked list pMalloc-> pNext = NULL; pCurrent-> pNext = pMalloc; pCurrent = pMalloc; // Move the current node down // reset key, value memset (keybuff, 0, KEY_SIZE); memset (valuebuff, 0, VALUE_SIZE );} // set the environment handle to * handle = ph; // close the file fclose (fp); return ret;} // obtain the number of attributes. 0 is returned successfully, return non-0 int getCount (void * handle, int * count) {int ret = 0, cn = 0; PROPS_HANDLE * ph = NULL; Properties * pCurrent = NULL; if (handle = NULL | count = NULL) {ret =-1; printf ("fun getCount error: % d from (handle = NULL | count = NULL) \ n ", ret); return ret;} ph = (PROPS_HANDLE *) handle; pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {cn ++; pCurrent = pCurrent-> pNext;} * count = cn; return ret;} // obtain the value based on the KEY and return 0, if not found, return non-0 value int getValue (void * handle, const char * key, char * value) {int ret = 0; PROPS_HANDLE * ph = NULL; properties * pCurrent = NULL; if (handle = NULL | key = NULL | value = NULL) {ret =-1; printf ("getValue error: % d from (handle = NULL | key = NULL | value = NULL) \ n ", ret); return ret;} ph = (PROP S_HANDLE *) handle; pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {if (strcmp (pCurrent-> key, key) = 0) {break;} pCurrent = pCurrent-> pNext;} if (pCurrent = NULL) {ret =-2; printf ("fun getValue warning: not found the key: % s \ n", key); return ret;} strcpy (value, pCurrent-> value); return ret;} // modify the attribute value corresponding to the key. If the modification succeeds, 0 is returned. If the modification fails, a non-0 int setValue (void * handle, const char * key, const char * value) {int ret = 0; PROPS_HANDLE * ph = NULL; Properties * pCurrent = NULL; I F (handle = NULL | key = NULL | value = NULL) {ret =-1; printf ("fun setValue error: % d from (handle = NULL | key = NULL | value = NULL) \ n ", ret); return ret ;} // obtain the environment handle ph = (PROPS_HANDLE *) handle; // obtain the header node pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {if (strcmp (pCurrent-> key, key) = 0) {// find break;} pCurrent = pCurrent-> pNext ;} if (pCurrent = NULL) {// key ret =-2 not found; printf ("fun setValue warning: not found the key: % s \ n", key ); return ret;} // modify the value strcpy (pCurrent-> value, value) of the key; if (strchr (value, '\ n') = NULL) {// Add a line break strcat (pCurrent-> value, "\ n");} // write the modified configuration item to the file ret = saveConfig (ph-> filepath, ph-> pHead); retur N ret;} // add an attribute. If the attribute is successfully added, 0 is returned. If the attribute fails to be added, non-0 int add (void * handle, const char * key, const char * value) is returned) {int ret = 0; PROPS_HANDLE * ph = NULL; Properties * pCurrent = NULL; if (handle = NULL | key = NULL | value = NULL) {ret =-1; printf ("fun add error: % d from (handle = NULL | key = NULL | value = NULL) \ n ", ret); return ret;} ph = (PROPS_HANDLE *) handle; // ----------- if the key exists in the linked list, modify it directly; otherwise, add it to the linked list --------- -- // PCurrent = ph-> pHead; while (pCurrent-> pNext! = NULL) {if (strcmp (pCurrent-> pNext-> key, key) = 0) {break;} pCurrent = pCurrent-> pNext ;} if (pCurrent-> pNext! = NULL) {return setValue (handle, key, value);} // ----------- the key does not exist. Create a new configuration item and add it to the linked list ----------- // Properties * pMalloc; ret = createPropsNode (& pMalloc); if (ret! = 0) {printf ("fun add error: % d from malloc new node. ", ret); return ret;} strcpy (pMalloc-> key, key); if (strchr (pCurrent-> value, '\ n') = NULL) {strcat (pCurrent-> value, "\ n");} strcpy (pMalloc-> value, value); if (strchr (value, '\ n') = NULL) {// Add a line break strcat (pMalloc-> value, "\ n");} pCurrent-> pNext = pMalloc; // Add the new configuration item to the linked list // write the new configuration item to the file ret = saveConfig (ph-> filepath, ph-> pHead); return ret;} // delete Attribute. If the deletion succeeds, 0 is returned. If the deletion fails, a non-0 int del (void * handle, const char * key) {int ret = 0; PROPS_HANDLE * ph = NULL is returned; properties * pCurrent = NULL, * pPrev = NULL; if (handle = NULL | key = NULL) {ret =-1; printf ("fun del error: % d from (handle = NULL | key = NULL) \ n ", ret); return ret;} ph = (PROPS_HANDLE *) handle; pPrev = ph-> pHead; pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {if (strcmp (pCurrent-> key, key) = 0) {break;} pPrev = pCurrent; // move the previous node down to pCurrent = pCurrent-> pNext; // move down the current node} if (pCurrent = NULL) {// ret =-2 not found; printf ("fun del warning: not found the key: % s \ n ", key); return ret;} pPrev-> pNext = pCurrent-> pNext; // Remove free (pCurrent) from the linked list ); // release the memory pCurrent = NULL; // save it to the file ret = saveConfig (ph-> filepath, ph-> pHead); return ret ;} // obtain all the keys in the property file, 0 is returned for successful retrieval, and a non-0 value is returned for int getKeys (void * handle, char *** keys, int * keyscount) {int ret = 0, count = 0, index = 0; PROPS_HANDLE * ph = NULL; Properties * pCurrent = NULL; char ** pKeys = NULL; if (handle = NULL | keys = NULL | keyscount = NULL) {ret =-1; printf ("fun getKeys error: % d from (handle = NULL | keys = NULL | keyscount = NULL) \ n ", ret); return ret ;} // obtain the number of configuration items ret = getCount (handle, & co Unt); if (ret! = 0) {printf ("fun getKeys error: % d from getCount \ n", ret); return ret;} ph = (PROPS_HANDLE *) handle; pCurrent = ph-> pHead-> pNext; // according to the length of the linked list, the applied memory space pKeys = (char **) malloc (sizeof (char *) * count ); if (pKeys = NULL) {ret =-2; printf ("fun getKeys error: % d from malloc keys \ n", ret); return ret ;} pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {pKeys [index] = pCurrent-> key; pCurrent = pCurrent-> pNext; index ++;} * keys = pKeys; * keyscount = count; return ret ;} // release the memory space of all keys. If 0 is returned successfully, the non-0 int free_keys (char *** keys, int * keyscount) {int ret = 0 is returned; if (keys = NULL | keyscount = NULL) {ret =-1; printf ("fun free_keys error: % d from (keys = NULL | keyscount = NULL) \ n ", ret); return ret;} free (* keys); * keys = NULL; * keyscount = 0; Return ret;} // get all values in the property file. If the value is successful, 0 is returned. If the value is failed, int getValues (void * handle, char *** values, int * valuescount) is returned) {int ret = 0, count = 0, index = 0; PROPS_HANDLE * ph = NULL; Properties * pCurrent = NULL; char ** pValues = NULL; if (handle = NULL | values = NULL | valuescount = NULL) {ret =-1; printf ("fun getValues error: % d from (handle = NULL | values = NULL | valuescount = NULL) \ n ", ret); return r Et;} // obtain the number of configuration items ret = getCount (handle, & count); if (ret! = 0) {printf ("fun getValues error: % d from getCount \ n", ret); return ret;} // apply for memory space, store all values pValues = (char **) malloc (sizeof (char *) * count); if (pValues = NULL) {ret =-2; printf ("fun getValues error: % d from malloc values \ n", ret); return ret;} ph = (PROPS_HANDLE *) handle; pCurrent = ph-> pHead-> pNext; while (pCurrent! = NULL) {pValues [index] = pCurrent-> value; pCurrent = pCurrent-> pNext; index ++;} * values = pValues; * valuescount = count; return ret ;} // release the memory space of all values. If 0 is returned successfully, the non-0 int free_values (char *** values, int * valuescount) {int ret = 0 is returned; if (values = NULL | valuescount = NULL) {ret =-1; printf ("fun free_values error: % d from (values = NULL | valuescount = NULL) \ n ", ret); return ret;} free (* values); * Values = NULL; * valuescount = 0; return ret;} // release the environment resource. If the environment resource is successfully released, 0 is returned. If the environment resource fails, a non-0 int release (void ** handle) is returned) {int ret = 0; PROPS_HANDLE * ph = NULL; if (handle = NULL) {ret =-1; printf ("release error: % d from (handler = NULL) \ n ", ret); return ret;} ph = (PROPS_HANDLE *) * handle; // release the linked list memory resource Properties * pCurr = ph-> pHead; properties * pTemp = NULL; while (pCurr! = NULL) {if (pCurr-> key! = NULL) {free (pCurr-> key); pCurr-> key = NULL;} if (pCurr-> value! = NULL) {free (pCurr-> value); pCurr-> value = NULL;} pTemp = pCurr-> pNext; free (pCurr); pCurr = pTemp ;} // release the memory space allocated by the configuration file path if (ph-> filepath! = NULL) {free (ph-> filepath); ph-> filepath = NULL;} // release the environment handle itself free (ph); * handle = NULL; // avoid wild pointer return ret;} // remove space static int trimeSpace (const char * src, char * dest) {int ret = 0; if (src = NULL | dest = NULL) {ret =-1; printf ("trimeSpace error: % d from (src = NULL | dest = NULL) \ n ", ret); return ret;} const char * psrc = src; unsigned long I = 0, j = strlen (psrc)-1, len; while (psrc [I] = '') {I ++;} while (psrc [j] ='') {j --;} len = j-I + 1; memcpy (dest, psrc + I, len); * (dest + len) = '\ 0'; return ret;} // create a node static int createPropsNode (Properties ** props) {int ret = 0; Properties * p = NULL; if (props = NULL) {ret =-100; printf ("createProps error: % d from (props = NULL) \ n ", ret); return ret;} p = (Properties *) malloc (sizeof (Properties); if (p = NULL) {ret =-200; printf ("CreateProps malloc % ld bytes error: % d \ n", sizeof (Properties), ret); return ret;} p-> key = (char *) malloc (KEY_SIZE ); p-> value = (char *) malloc (VALUE_SIZE); p-> pNext = NULL; * props = p; return ret ;} // save it to the static int saveConfig (const char * filepath, Properties * head) {int ret = 0, writeLen = 0; FILE * fp = NULL; Properties * pCurrent = NULL; if (filepath = NULL | head = NULL) {ret =-100; printf ("fu N saveConfig error: % d from (filepath = NULL | head = NULL) \ n ", ret); return ret;} fp = fopen (filepath, "w"); if (fp = NULL) {ret =-200; printf ("fun saveConfig: open file error: % d from % s \ n", ret, filepath); return ret;} pCurrent = head-> pNext; while (pCurrent! = NULL) {writeLen = fprintf (fp, "% s = % s", pCurrent-> key, pCurrent-> value); // return the number of written bytes, if an error occurs, a negative value if (writeLen <0) {// TODO is returned. if the write fails, how can I roll back the written data ??? Ret =-300; printf ("fun saveConfig err: % d from (% s = % s) \ n", ret, pCurrent-> key, pCurrent-> value ); break;} pCurrent = pCurrent-> pNext;} fclose (fp); // close the file return ret ;}
3. Test code
(Create props.txt in the project root directory)
//// Main. c // read/write configuration file /// Created by Yang Xin on 14-4-24. // Copyright (c) 2014 yangxin. all rights reserved. // # include
# Include
# Include
# Include "Properties. h "int main (int argc, const char * argv []) {int ret; void * handle; const char * filepath ="/Users/yangxin/Desktop/props.txt "; // initialize ret = init (filepath, & handle); if (ret! = 0) {printf ("env init error: % d \ n", ret); return 0;} char valuebuf [128]; // test the configuration item ret = getValue (handle, "host", valuebuf); if (ret = 0) {printf ("value = % s \ n ", valuebuf);} else {printf ("failed to get the value of host \ n");} // test the configuration item ret = setValue (handle, "version ", "1.2.3"); if (ret = 0) {printf ("modified successfully! \ N ");} else {printf (" failed to modify \ n ");} // test adding configuration item ret = add (handle," pool_connection_countxx "," 2000 "); if (ret = 0) {printf ("added successfully! \ N ") ;}else {printf (" failed to add \ n ");} // test the deletion configuration item ret = del (handle," connectionMax "); if (ret = 0) {printf ("deleted successfully! \ N ") ;}else {printf (" failed to delete \ n ");} // test the key char ** keys = NULL for obtaining all configuration items; int keyscount; ret = getKeys (handle, & keys, & keyscount); if (ret = 0) {printf ("A total of % d keys \ n", keyscount ); for (int I = 0; I
Test configuration file:
username=rootpassword=root123456host=192.168.1.100port=9090connectionMax=200version=1.0
Test results:
: Git@github.com: xyang0917/RWAppProperites. git