C語言實現ini解析函式 getPrivateProfileString
阿新 • • 發佈:2019-01-25
// // myGetProfileLine.c // Version 0.9.3 // // Created by LancerLian on 15-1-21. // #include #include #include #include #include #define ERROR -1 #define MAXSIZE 1024 long myGetPrivateProfileString (char *lpAppName,char *lpKeyName,char *lpDefault,char *lpReturnedString,int nSize,char* lpFileName); int main() { char *strFileName = "initest.txt"; int ret = 0; char *szKeyValue = (char *) malloc (MAXSIZE * sizeof(char)); //szKeyValue用於存入get到的值 ret = myGetPrivateProfileString( "player", "name", "Default:Williams", szKeyValue, 25, strFileName); printf("ret = %d, szKeyValue = %s \n", ret, szKeyValue); return 0; } long myGetPrivateProfileString (char *lpAppName, char *lpKeyName, char *lpDefault, char *lpReturnedString, int nSize, char *lpFileName) { //初始化返回字串 memset (lpReturnedString, 0, nSize * sizeof(char)); int ret = 0; bool bIsfind = false; FILE *fp = NULL; fp = fopen (lpFileName, "r"); if (!fp) { printf("Fail to fopen!\n"); return ERROR; //初始化檔案失敗,返回'0x2' } int nAppNameLen = 0; int nKeyNameLen = 0; bool bIsFindAppName = false; bool bIsFindKeyName = false; char *szReadBuffer = NULL; char *szLineStart = NULL; char *szLineEnd = NULL; char *szEnd = NULL; char *szNextLine = NULL; char *szValueStart = NULL; char szTempAppName[MAXSIZE] = ""; char szTempKeyName[MAXSIZE] = ""; char *szTempValue = NULL; char *szCopySectionName = (char *) malloc (nSize * sizeof(char)); char *szCopyKeyName = (char *) malloc (nSize * sizeof(char)); char szSectionList[MAXSIZE] = ""; char szKeyList[MAXSIZE] = ""; if (!szCopyKeyName || !szCopySectionName) { printf("malloc error!\n"); ret = ERROR; goto _OUT; //_OUT: 統一釋放記憶體並返回值 } int len = 0; int defLen = 0; bool bSectionCopyOver = false; bool bEntryCopyOver = false; memset(szCopySectionName, 0, nSize); memset(szCopyKeyName, 0, nSize); char *p = szCopySectionName; char *q = szCopyKeyName; int pLen = nSize - 1; //能用於存AppName的空間長度 int qLen = nSize - 1; //能用於存KeyName的空間長度 //算出檔案長度,並將指標返回檔案開頭 fseek(fp,0,SEEK_END); long nFileSize = ftell(fp); fseek(fp,0,SEEK_SET); //檔案長度為空,則返回預設值 if (nFileSize == 0) { defLen = (int)strlen(lpDefault); if (nSize <= defLen) { strncpy(lpReturnedString, lpDefault, nSize - 1); lpReturnedString[nSize - 1] = '\0'; ret = nSize - 1; } else { strncpy(lpReturnedString, lpDefault, defLen); ret = defLen; } fclose(fp); return ret; } //檔案不為空,則存入szReadBuffer else { szReadBuffer = (char *)malloc((nFileSize + 1) * sizeof(char)); if (!szReadBuffer) { printf("malloc failed!\n"); goto _OUT; //_OUT: 統一釋放記憶體並返回值 } //初始化szReadBuffer,並讀入檔案 memset(szReadBuffer, 0, nFileSize + 1); if (!fread(szReadBuffer,sizeof(char),nFileSize,fp)) ///將檔案讀入szReadBuffer { goto _OUT; //_OUT: 統一釋放記憶體並返回值 } } len = (int) strlen(szReadBuffer); szNextLine = szReadBuffer; szEnd = szReadBuffer + len; //此部分分析存入Buffer中檔案 while (szNextLine < szEnd) { szLineStart = szNextLine; szNextLine = (char *)memchr (szLineStart, '\n', szEnd - szLineStart); //移至換行符 //若無換行符,szNextLine移至回車 if (!szNextLine) szNextLine = (char *)memchr (szLineStart, '\r', szEnd - szLineStart); //回車 //若既無換行符又無回車,則szNextLine指向szEnd if (!szNextLine) szNextLine = szEnd; else szNextLine++; szLineEnd = szNextLine; //行結尾 ///跳過前後空格,使得指標分別指向關鍵字的開頭和結尾 while (szLineStart < szLineEnd && isspace((unsigned char)*szLineStart)) { szLineStart++; } while ((szLineEnd > szLineStart) && isspace((unsigned char)szLineEnd[-1])) { szLineEnd--; } if (szLineStart >= szLineEnd) continue; //跳出本次迴圈,進入下一次 //section 開始分析 if (*szLineStart == '[') { if (bIsFindAppName) { bEntryCopyOver = true; //AppName 找到 } char *szAppNameEnd; if ((szAppNameEnd = (char *) memchr(szLineStart, ']', szLineEnd - szLineStart ))) { szLineStart++; //跳過[ len =(int) (szAppNameEnd - szLineStart); //求出section的長度 strncpy(szTempAppName,szLineStart,len); //儲存AppName szTempAppName[len] = '\0'; //將所有Section名稱拷貝至 szCopySectionName buffer if (!bSectionCopyOver) { int tempAppLen = (int)strlen(szTempAppName) + 1; if (tempAppLen >= pLen) { if (pLen > 0) { strncpy(p, szTempAppName,pLen); p += pLen - 1; *p++ = '\0'; } *p = '\0'; ret = nSize - 2 ; bSectionCopyOver = true; } else { strncpy(p, szTempAppName, tempAppLen - 1); strncpy(p + tempAppLen - 1, "\t", 1); } p += tempAppLen; pLen -= tempAppLen; } if (lpAppName) { //AppName找到 nAppNameLen = strlen (lpAppName); if (0 == strncmp(szTempAppName,lpAppName,nAppNameLen) && szTempAppName[nAppNameLen] == '\0') ///////////// bIsFindAppName = true; } continue; } } len =(int) (szLineEnd - szLineStart); //查詢等號 if ((szValueStart = (char *)memchr( szLineStart, '=', szLineEnd - szLineStart)) != NULL) { const char *szKeyNameEnd = szValueStart; //KeyName結束與鍵值開始 while (szKeyNameEnd > szLineStart &&isspace((unsigned char)szKeyNameEnd[-1])) szKeyNameEnd--; //去掉Key後面的空格 len = (int)(szKeyNameEnd - szLineStart); szValueStart++;//跳過等號,指向數值 while (szValueStart < szLineEnd && isspace((unsigned char)*szValueStart)) szValueStart++; //跳過空格 //存入鍵值 if (len > 0 && bIsFindAppName) { strncpy(szTempKeyName,szLineStart,len); szTempKeyName[len] = '\0'; //若AppName找到,將所有KeyName存入szCopyKeyName if (!bEntryCopyOver) { int tempKeyLen =(int) strlen(szTempKeyName) + 1; if (tempKeyLen >= qLen) { if (qLen > 0) { strncpy(q, szTempKeyName,qLen); q += qLen-1; *q++ = '\0'; } *q = '\0'; ret = nSize - 2 ; bEntryCopyOver = true; } else { strncpy(q, szTempKeyName, tempKeyLen - 1); strncpy(q + tempKeyLen - 1, "\t", 1); } q += tempKeyLen; qLen -= tempKeyLen; } //拷貝鍵值到szTempValue if (lpKeyName) { nKeyNameLen = strlen (lpKeyName); if (0 == strncmp(szTempKeyName, lpKeyName, nKeyNameLen) && szTempKeyName[nKeyNameLen] == '\0') // AppName 和 keyName 找到 { bIsFindKeyName = true; len = (int)(szLineEnd - szValueStart ); szTempValue =(char*) malloc(len + 1); memcpy(szTempValue, szValueStart, len * sizeof(char)); szTempValue[len] = '\0'; break; } } } } } // KeyName找到 if(bIsFindKeyName) { if (szTempValue) { len =(int) strlen(szTempValue); if (nSize>len) { strncpy(lpReturnedString,szTempValue,len); ret =len; } else { strncpy(lpReturnedString,szTempValue,nSize-1); lpReturnedString[nSize-1]='\0'; ret = nSize -1; } } else ret=0; } //找到Section, 但是沒有找到key else if(bIsFindAppName) { if (!lpKeyName) { len =(int) strlen(szCopyKeyName); strncpy(lpReturnedString, szCopyKeyName, len); ret = len - 1; } else { if (lpDefault == NULL) { printf ("ERROR! lpDefault == NULL.\n"); return ERROR; } len = (int)strlen(lpDefault); if (nSize>len) { strncpy(lpReturnedString,lpDefault,len); ret = len; } else { strncpy(lpReturnedString,lpDefault,nSize - 1); lpReturnedString[nSize - 1] = '\0'; ret = nSize - 1; } } } //未找到Section else { if (!lpAppName) { len =(int) strlen(szCopySectionName); strncpy(lpReturnedString, szCopySectionName, len); ret =len; } else { len = (int)strlen(lpDefault); if (nSize > len) { strncpy(lpReturnedString, lpDefault, len); ret = len; } else { strncpy(lpReturnedString,lpDefault,nSize - 1); lpReturnedString[nSize - 1] = '\0'; ret = nSize - 1; } } } //_OUT: 統一釋放記憶體並返回值 _OUT: if(szCopySectionName) free(szCopySectionName); if(szCopyKeyName) free(szCopyKeyName); if(szReadBuffer) free(szReadBuffer); if(szTempValue) free(szTempValue); fclose(fp); return ret; }