📄 ini.c
字号:
}; /* ** Variable wasn't found. If we don't want it, ** then ignore it */ } case NotInSection: break; /* Not interested in this line */ case NewSection: break; /* Who cares? It's not our section */ case FoundSection: break; /* We found our section! */ case LeavingSection: break; /* We finished our section! */ } if (-1 == retval) break; } if (ferror(CfgFile)) { fclose(CfgFile); return -2; } else { fclose(CfgFile); return retval; }}/*** SearchCfg() - Search an .ini / .cfg file for a specific single datum.**** Parameters: 1 - File name.** 2 - Section name.** 3 - Variable to find.** 4 - Pointer to variable's storage.** 5 - Type of vatiable.**** Returns: 1 if succesful** 0 if section/variable not found** -1 if invalid type spec** -2 for file error*/int SearchCfg(const char *FileName, char *SectionName, char *VarName, void *DataPtr, enum CfgTypes VarType ){ struct CfgStruct MyVars[2]; MyVars[0].Name = VarName; MyVars[0].DataPtr = DataPtr; MyVars[0].VarType = VarType; MyVars[1].Name = MyVars[1].DataPtr = NULL; return ReadCfg(FileName, SectionName, MyVars);}/*** UpdateCfg() - This will update a variable in a specific section in your** .ini file. It will do so safely by copying it to a new file,** and when finished, will delete the old one and rename the** new one to the correct name. If any fatal error occurs, it** will return a -1 to indiate failure. I generally don't care** why it failed, just knowing that it failed is usually enough.**** Paramters: 1 - File name.** 2 - Section name.** 3 - Variable tag.** 4 - Pointer to textual representation of the variable's value.**** Returns: -1 if a file error occurred, else 0.**** Notes: 1. If the section doesn't yet exist in the file, it will be added.** 2. If the variable doesn't yet exist in the file, it will be added.** 3. New variables are created at the end of existing sections, or** on the last line before the first section name in the case where** the section name is "".** 4. New sections are created at the end of the file.*/int UpdateCfg(const char *FileName, char *SectionName, char *VarWanted, char *NewData){ FILE *CfgFile; char line[BUFFERSIZE]; char SectionWanted[BUFFERSIZE]; char CurrentSection[BUFFERSIZE]; enum LineTypes linetype; char var[BUFFERSIZE]; char data[BUFFERSIZE]; char TempFileName[FILENAME_MAX]; FILE *NewCfgFile; int Error = 0; int updated = 0; CfgFile = cant((char *)FileName, "r"); strcpy(TempFileName, FileName); chgext(TempFileName, NULL, "tmp"); NewCfgFile = cant(TempFileName, "w"); strcpy(CurrentSection, "[]"); sprintf(SectionWanted, "[%s]", SectionName); while (EOF != ReadLine(CfgFile, line)) { linetype = SectionLine(line, SectionWanted, CurrentSection); switch (linetype) { case InSection: /* In our section, parse it. */ ParseLine(line, var, data); if ((StrEq(var, VarWanted)) && (!updated)) { strncpy(data, NewData, BUFFERSIZE); data[BUFFERSIZE-1] = NUL; updated = 1; } fprintf(NewCfgFile, "%s = %s\n", var, data); break; case EmptyLine: /* Fall Through. Just copy it. */ case CommentLine: /* Fall Through. Just copy it. */ case NotInSection: /* Fall Through. Just copy it. */ case NewSection: /* Fall Through. Just copy it. */ case FoundSection: /* Fall Through. Just copy it. */ fprintf(NewCfgFile, "%s\n", line); break; case LeavingSection: /* Leaving section, may have to add it */ if (!updated) /* Variable wasn't found, we have */ { /* to add it. */ fprintf(NewCfgFile, "%s = %s\n", VarWanted, NewData); updated = 1; } /* ** Now print current line */ fprintf(NewCfgFile, "%s\n", line); break; } } /* ** Our section may not have even been there, in which case we have ** to add both the variable and the section itself. */ if (!updated) { /* We may have hit EOF while still in our section. */ /* If so, we don't need to add the section header. */ if (!StrEq(CurrentSection, SectionWanted)) fprintf(NewCfgFile, "%s\n", SectionWanted); fprintf(NewCfgFile, "%s = %s\n", VarWanted, NewData); } if (ferror(CfgFile)) Error = -1; if (ferror(NewCfgFile)) Error = -1; fclose(CfgFile); fclose(NewCfgFile); if (!Error) { if (remove(FileName)) return -1; if (rename(TempFileName, FileName)) return -1; } return Error;}#ifdef TEST#include <stdlib.h>#if defined(MSDOS) || defined (_MSDOS_) #define PINI_fname "prices.ini"#else #define PINI_fname "/home/mars_nwe/engr/disp/prices.ini"#endifFILE *log_ = stderr;main(){ char Line[INI_LINESIZE]; int Int; long Long; double Double; Boolean_T Bool; struct CfgStruct this_var; FILE* tst; long prices[2]; /* ** First work with a test file */ tst = cant("test.ini", "w"); fputs("[Section 1]\n", tst); fputs("[Section 2]\n", tst); fputs("[Section 3]\n", tst); fputs("[Section 4]\n", tst); fputs("[Section 5]\n", tst); fputs("[Section 6]\n", tst); fclose(tst); puts("Updating the test configuration file"); puts("Updating section 1"); UpdateCfg("test.ini", "Section 1", "string #1", "section 1 test"); puts("Updating section 2"); UpdateCfg("test.ini", "Section 2", "short #2", "2"); puts("Updating section 3"); UpdateCfg("test.ini", "Section 3", "long #3", "3"); UpdateCfg("test.ini", "Section 4", "double #4", "4.4"); UpdateCfg("test.ini", "Section 5", "boolean #5", "Y"); UpdateCfg("test.ini", "Section 6", "boolean #6", "N"); UpdateCfg("test.ini", "", "global string", "\"Hello, world!\" ;Comment"); puts("I've finished the updates, now to try to get the data back"); this_var.Name = "global string"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(0) returned %d; Line=\n", ReadCfg("test.ini", "", &this_var)); puts(Line); this_var.Name = "string #1"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(1) returned %d; Line=\n", ReadCfg("test.ini", "Section 1", &this_var)); puts(Line); this_var.Name = "short #2"; this_var.DataPtr = ∬ this_var.VarType = Cfg_Short; printf("ReadCfg(2) returned %d; Value= ", ReadCfg("test.ini", "Section 2", &this_var)); printf("%d\n", Int); this_var.Name = "long #3"; this_var.DataPtr = &Long; this_var.VarType = Cfg_Long; printf("ReadCfg(3) returned %d; Value = ", ReadCfg("test.ini", "Section 3", &this_var)); printf("%ld\n", Long); this_var.Name = "double #4"; this_var.DataPtr = &Double; this_var.VarType = Cfg_Double; printf("ReadCfg(4) returned %d; Value = ", ReadCfg("test.ini", "Section 4", &this_var)); printf("%f\n", Double); this_var.Name = "boolean #5"; this_var.DataPtr = &Bool; this_var.VarType = Cfg_Boolean; printf("ReadCfg(5) returned %d; Value = ", ReadCfg("test.ini", "Section 5", &this_var)); printf("%c\n", Bool ? 'T' : 'F'); this_var.Name = "boolean #6"; this_var.DataPtr = &Bool; this_var.VarType = Cfg_Boolean; printf("ReadCfg(6) returned %d; Value = ", ReadCfg("test.ini", "Section 6", &this_var)); printf("%c\n", Bool ? 'T' : 'F'); /* ** Look for non-existant sections and/or variables */ Line[0] = NUL; this_var.Name = "string #99"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(99) returned %d; Line=\n", ReadCfg("test.ini", "Section 99", &this_var)); puts(Line); Line[0] = NUL; this_var.Name = "string #99"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(0/99) returned %d; Line=\n", ReadCfg("test.ini", "", &this_var)); puts(Line); Line[0] = NUL; this_var.Name = "string #99"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(1/99) returned %d; Line=\n", ReadCfg("test.ini", "Section 1", &this_var)); puts(Line); Line[0] = NUL; this_var.Name = "string #1"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(1/100) returned %d; Line=\n", ReadCfg("test.ini", "Section 100", &this_var)); puts(Line); /* ** Next, add a section and new variables */ UpdateCfg("test.ini", "", "new global variable", "abc"); UpdateCfg("test.ini", "Section -1", "new variable", "xyz"); /* ** Next work with a sample real PRICES.INI file */ this_var.Name = "Price of #1"; this_var.DataPtr = &prices[0]; this_var.VarType = Cfg_Long; printf("ReadCfg(1) returned %d; Value = ", ReadCfg(PINI_fname, "", &this_var)); printf("%ld\n", prices[0]); this_var.Name = "Price of #2"; this_var.DataPtr = &prices[1]; this_var.VarType = Cfg_Long; printf("ReadCfg(2) returned %d; Value = ", ReadCfg(PINI_fname, "", &this_var)); printf("%ld\n", prices[1]); UpdateCfg("prices.ini", "", "Price of #2", "999"); this_var.Name = "Price of #2"; this_var.DataPtr = &prices[1]; this_var.VarType = Cfg_Long; printf("ReadCfg(2) returned %d; Value = ", ReadCfg(PINI_fname, "", &this_var)); printf("%ld\n", prices[1]); UpdateCfg(PINI_fname, "", "Price of #2", "389"); this_var.Name = "Price of #2"; this_var.DataPtr = &prices[1]; this_var.VarType = Cfg_Long; printf("ReadCfg(2) returned %d; Value = ", ReadCfg(PINI_fname, "", &this_var)); printf("%ld\n", prices[1]); /* ** Finally, try an invalid file name */ this_var.Name = "global string"; this_var.DataPtr = Line; this_var.VarType = Cfg_String; printf("ReadCfg(0) returned %d; Line=\n", ReadCfg("none.ini", "", &this_var)); puts(Line); return EXIT_SUCCESS;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -