📄 gcftxtf.c
字号:
/* 通用C语言函数:文本文件有关操作,.CFG/.INI类配置文件读写。我们知道WINDOWS下的软件可以使用.INI文件处理程序配置,那么在DOS、UNIX上又如何才能读写.CFG/.INI类配置文件? 你可以使用本程序的有关函数很方便地实现。 GCFTXTF.C -- General C functions for Text File Read/Write M.L.Y 2000.1.1 MODIFIED (YYYY.MM.DD) M.L.Y 2000.01.01 - Creation*/#include "GCFTXTF.H"struct txt_line_flds txt_line_fld[MAX_TXT_LINE_FLD];char CFG_ssl = '[', CFG_ssr = ']'; /* .CFG/.INI file section symbol */int CFG_section_line_no, CFG_key_line_no, CFG_key_lines;/* ------------------------------------------------------------------------- *//* Read 1 line text into *buffer from file *fp, return length actually read. maxlen --- max. length of *buffer CR or LF is not put into *buffer FF(0x0C) is put into *buffer and then return Ctrl-Z(0x1A) is put into *buffer and then return If EOF was detected then return -1 If an error occurred then return -2 M.L.Y 1995.06.09, 07.31, 1998.9.9*/int fgetline(FILE *fp, USGC *buffer, int maxlen){ int i, j, NoteCount; USGC ch1; NoteCount=0; for(i = 0, j = 0; i < maxlen; j++) { if(fread(&ch1, sizeof(USGC), 1, fp) != 1) { if(feof(fp) != 0) { if(j == 0) return -1; /* EOF */ else break; } if(ferror(fp) != 0) return -2; /* error */ return -2; }else { if(ch1=='/') NoteCount++; //Note else NoteCount=0; if(NoteCount==2) { i--; break; } if(ch1 == '\n' || ch1 == 0x00) break; /* end of line */ if(ch1 == '\f' || ch1 == 0x1A) /* '\f': Form Feed */ { buffer[i++] = ch1; break; } if(ch1 != '\r') buffer[i++] = ch1; /* ignore CR */ } } buffer[i] = '\0'; return i;}/* ------------------------------------------------------------------------- *//* Copy source_file to dest_file Return code: 0 -- Ok <0 -- Error M.L.Y 1996.7, 2000.11*/int copy_txt_file(void *source_file, void *dest_file){ FILE *fp1, *fp2; USGC buf[1024+1]; int rc; if((fp1 = fopen((char *)source_file, "r")) == NULL) return COPYF_ERR_OPEN_FILE; rc = COPYF_ERR_CREATE_FILE; if((fp2 = fopen((char *)dest_file, "w")) == NULL) goto copy_end; while(1) { rc = COPYF_ERR_READ_FILE; memset(buf, 0x00, 1024+1); if(fgets((char *)buf, 1024, fp1) == NULL) { if(mstrlen(buf) == 0) { if(ferror(fp1) != 0) goto copy_end; break; /* EOF */ } } rc = COPYF_ERR_WRITE_FILE; if(fputs((char *)buf, fp2) == EOF) goto copy_end; } rc = COPYF_OK;copy_end: if(fp2 != NULL) fclose(fp2); if(fp1 != NULL) fclose(fp1); return rc;}/* ------------------------------------------------------------------------- */int split_txt_line_fld(char *txt_line, char *sep_chars)/* Split a text line fields info to struct txt_line_fld Return fld number e.g.: fld1 = fld2, fld3, "fld4", 'fld5' key = value M.L.Y 2000.8.2*/{ int i, j, k, n, stat = 0, quote_stat = 0; char quote; n = strlen(txt_line); for(i = 0, j = 0, k = 0; i <= n; i++) { if(i >= n || (strchr(sep_chars, txt_line[i]) != NULL && quote_stat == 0)) { if(stat == 0) continue; stat = 0; /* is separate char */ txt_line_fld[k].fldsp = j; txt_line_fld[k].fldlen = i - j; k++; } else { if(txt_line[i] == '\'' || txt_line[i] == '\"') { if(quote_stat == 0) { quote = txt_line[i]; /* " or ' */ quote_stat = 1; /* enter " " or ' ' */ } else { if(txt_line[i] == quote) quote_stat = 0; /* withdraw from " " or ' ' */ } } if(stat == 1) continue; stat = 1; /* is normal char */ j = i; /* fld start pointer */ } } return k; /* fld number */}/* ------------------------------------------------------------------------- */char *get_txt_line_fld(char *txt_line, int fldno, char *buf)/* After split a text line fields info to struct txt_line_fld, get the fldno fld to buf Return buf M.L.Y 2000.8.2*/{ memmove(buf, txt_line + txt_line_fld[fldno].fldsp, txt_line_fld[fldno].fldlen); buf[txt_line_fld[fldno].fldlen] = '\0'; return buf;}/* ------------------------------------------------------------------------- */int split_key_val(USGC *buf, USGC **key, USGC **val)/* Split key=val pair: xxx = yyyyyyyy | | | k1 k2 i return: 1 --- ok 0 --- blank line -1 --- no key, "= val" -2 --- only key, no '=' M.L.Y 2000.8, 2000.11*/{ int i, k1, k2, n; if((n = strlen((char *)buf)) < 1) return 0; for(i = 0; i < n; i++) if(buf[i] != ' ' && buf[i] != '\t') break; if(i >= n) return 0; if(buf[i] == '=') return -1; k1 = i; for(i++; i < n; i++) if(buf[i] == '=') break; if(i >= n) return -2; k2 = i; for(i++; i < n; i++) if(buf[i] != ' ' && buf[i] != '\t') break; buf[k2] = '\0'; *key = buf + k1; *val = buf + i; return 1;}/* ------------------------------------------------------------------------- */int CFG_get_key(void *CFG_file, void *section, void *key, void *buf)/* Note: section --- not include [] or {} key --- may include blank space blank line or begin with ';' for remarks line end with '+' for line to be continued Return: 0 --- ok <0 --- error*/{ FILE *fp; USGC buf1[MAX_CFG_BUF + 1], buf2[MAX_CFG_BUF + 1]; USGC *key_ptr, *val_ptr; int line_no, n, rc; line_no = 0; CFG_section_line_no = 0; CFG_key_line_no = 0; CFG_key_lines = 0; if((fp = fopen((char *)CFG_file, "rb")) == NULL) return CFG_ERR_OPEN_FILE; while(1) /* seek section */ { rc = CFG_ERR_READ_FILE; n = fgetline(fp, buf1, MAX_CFG_BUF); if(n < -1) goto r_cfg_end; rc = CFG_SECTION_NOT_FOUND; if(n < 0) goto r_cfg_end; /* EOF, not found */ line_no++; n = mstrlen(ltrimstr(rtrimstr(buf1))); if(n == 0 || buf1[0] == ';') continue; /* blank/remarks line */ rc = CFG_ERR_FILE_FORMAT; if(n > 2 && ((buf1[0] == '[' && buf1[n-1] != ']') || (buf1[0] == '{' && buf1[n-1] != '}'))) goto r_cfg_end; if(buf1[0] == '[' || buf1[0] == '{') { buf1[n-1] = 0x00; if(mstrcmp(buf1+1, section) == 0) break; /* section found */ } } CFG_section_line_no = line_no; while(1) /* seek key */ { rc = CFG_ERR_READ_FILE; n = fgetline(fp, buf1, MAX_CFG_BUF); if(n < -1) goto r_cfg_end; rc = CFG_KEY_NOT_FOUND; if(n < 0) goto r_cfg_end; /* EOF, key not found */ line_no++; CFG_key_line_no = line_no; CFG_key_lines = 1; n = mstrlen(ltrimstr(rtrimstr(buf1))); if(n == 0 || buf1[0] == ';') continue; /* blank/remarks line */ rc = CFG_KEY_NOT_FOUND; if(buf1[0] == '[' || buf1[0] == '{') goto r_cfg_end; if(buf1[n-1] == '+') /* to be continued */ { buf1[n-1] = 0x00; while(1) { rc = CFG_ERR_READ_FILE; n = fgetline(fp, buf2, MAX_CFG_BUF); if(n < -1) goto r_cfg_end; if(n < 0) break; /* EOF */ line_no++; CFG_key_lines++; n = mstrlen(rtrimstr(buf2)); rc = CFG_ERR_EXCEED_BUF_SIZE; if(n > 0 && buf2[n-1] == '+') /* to be continued */ { buf2[n-1] = 0x00; if(mstrlen(buf1) + mstrlen(buf2) > MAX_CFG_BUF) goto r_cfg_end; mstrcat(buf1, buf2); continue; } if(mstrlen(buf1) + mstrlen(buf2) > MAX_CFG_BUF) goto r_cfg_end; mstrcat(buf1, buf2); break; } } rc = CFG_ERR_FILE_FORMAT; if(split_key_val(buf1, &key_ptr, &val_ptr) != 1) goto r_cfg_end; ltrimstr(rtrimstr(key_ptr)); if(mstrcmp(key_ptr, key) != 0) continue; /* not same key */ mstrcpy(buf, val_ptr); break; } rc = CFG_OK;r_cfg_end: if(fp != NULL) fclose(fp); return rc;}/* ------------------------------------------------------------------------- */int CFG_set_key(void *CFG_file, void *section, void *key, void *buf)/* Note: section --- not include [] or {} key --- may include blank space not use '+' for line to be continued Return: 0 --- ok <0 --- error*/{ FILE *fp1, *fp2; USGC buf1[MAX_CFG_BUF + 1], buf2[MAX_CFG_BUF + 1]; int line_no, line_no1, n, rc, rc2; char *tmpfname; rc = CFG_get_key(CFG_file, section, key, buf1); if(rc <= CFG_ERR && rc != CFG_ERR_OPEN_FILE) return rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -