📄 ugk_string.cpp
字号:
{ UGK_Free(*ppszDst); *ppszDst = NULL; } } else { /* Store the strings to remove in a new StringList */ *ppapszRetStrings = (char **)UGK_Calloc(nNumToRemove+1, sizeof(char*)); for (i=0; i < nNumToRemove; i++) { (*ppapszRetStrings)[i] = *ppszDst; *ppszDst = NULL; ppszDst++; } } /* Shift down all the lines that follow the lines to remove. */ if (nFirstLineToDelete == -1 || nFirstLineToDelete > nSrcLines) nFirstLineToDelete = nDstLines; ppszSrc = papszStrList + nFirstLineToDelete + nNumToRemove; ppszDst = papszStrList + nFirstLineToDelete; for ( ; *ppszSrc != NULL; ppszSrc++, ppszDst++) { *ppszDst = *ppszSrc; } /* Move the NULL pointer at the end of the StringList */ *ppszDst = *ppszSrc; /* At this point, we could realloc() papszStrList to a smaller size, but * since this array will likely grow again in further operations on the * StringList we'll leave it as it is. */ return papszStrList;}/************************************************************************//* GetsFromFile() *//* *//* Note: CR = \r = ASCII 13 *//* LF = \n = ASCII 10 *//************************************************************************//** * Reads in at most one less than nBufferSize characters from the fp * stream and stores them into the buffer pointed to by pszBuffer. * Reading stops after an EOF or a newline. If a newline is read, it * is _not_ stored into the buffer. A '\0' is stored after the last * character in the buffer. All three types of newline terminators * recognized by the CPLFGets(): single '\r' and '\n' and '\r\n' * combination. * * @param pszBuffer pointer to the targeting character buffer. * @param nBufferSize maximum size of the string to read (not including * termonating '\0'). * @param fp file pointer to read from. * @return pointer to the pszBuffer containing a string read * from the file or NULL if the error or end of file was encountered. */char *GetsFromFile( char *pszBuffer, int nBufferSize, FILE * fp ){ int nActuallyRead, nOriginalOffset; if ( nBufferSize == 0 || pszBuffer == NULL || fp == NULL ) return NULL;/* -------------------------------------------------------------------- *//* Let the OS level call read what it things is one line. This *//* will include the newline. On windows, if the file happens *//* to be in text mode, the CRLF will have been converted to *//* just the newline (LF). If it is in binary mode it may well *//* have both. *//* -------------------------------------------------------------------- */ nOriginalOffset = ftell( fp ); if( fgets( pszBuffer, nBufferSize, fp ) == NULL ) return NULL; nActuallyRead = strlen(pszBuffer); if ( nActuallyRead == 0 ) return NULL;/* -------------------------------------------------------------------- *//* Trim off \n, \r or \r\n if it appears at the end. We don't *//* need to do any "seeking" since we want the newline eaten. *//* -------------------------------------------------------------------- */ if( nActuallyRead > 1 && pszBuffer[nActuallyRead-1] == 10 && pszBuffer[nActuallyRead-2] == 13 ) { pszBuffer[nActuallyRead-2] = '\0'; } else if( pszBuffer[nActuallyRead-1] == 10 || pszBuffer[nActuallyRead-1] == 13 ) { pszBuffer[nActuallyRead-1] = '\0'; }/* -------------------------------------------------------------------- *//* Search within the string for a \r (MacOS convention *//* apparently), and if we find it we need to trim the string, *//* and seek back. *//* -------------------------------------------------------------------- */ char *pszExtraNewline = strchr( pszBuffer, 13 ); if( pszExtraNewline != NULL ) { int chCheck; nActuallyRead = pszExtraNewline - pszBuffer + 1; *pszExtraNewline = '\0'; fseek( fp, nOriginalOffset + nActuallyRead - 1, SEEK_SET ); /* * This hackery is necessary to try and find our correct * spot on win32 systems with text mode line translation going * on. Sometimes the fseek back overshoots, but it doesn't * "realize it" till a character has been read. Try to read till * we get to the right spot and get our CR. */ chCheck = fgetc( fp ); while( (chCheck != 13 && chCheck != EOF) || ftell(fp) < nOriginalOffset + nActuallyRead ) { static int bWarned = FALSE; if( !bWarned ) { bWarned = TRUE; // CPLDebug( "CPL", "CPLFGets() correcting for DOS text mode translation seek problem." ); } chCheck = fgetc( fp ); } } return pszBuffer;}#define UGKSPrintf_BUF_SIZE 8000#define UGKSPrintf_BUF_Count 10static char gszUGKSPrintfBuffer[UGKSPrintf_BUF_Count][UGKSPrintf_BUF_SIZE];static int gnUGKSPrintfBuffer = 0;const char *UGKSPrintf(char *fmt, ...){ va_list args; va_start(args, fmt); vsprintf(gszUGKSPrintfBuffer[gnUGKSPrintfBuffer], fmt, args); va_end(args); int nCurrent = gnUGKSPrintfBuffer; if (++gnUGKSPrintfBuffer == UGKSPrintf_BUF_Count) gnUGKSPrintfBuffer = 0; return gszUGKSPrintfBuffer[nCurrent];}/********************************************************************** * CSLAppendPrintf() * * Use UGKSPrintf() to append a new line at the end of a StringList. * * Returns the modified StringList. **********************************************************************/char **AppendPrintf(char **papszStrList, char *fmt, ...){ va_list args; va_start(args, fmt); vsprintf(gszUGKSPrintfBuffer[gnUGKSPrintfBuffer], fmt, args); va_end(args); int nCurrent = gnUGKSPrintfBuffer; if (++gnUGKSPrintfBuffer == UGKSPrintf_BUF_Count) gnUGKSPrintfBuffer = 0; return AddStringToList(papszStrList, gszUGKSPrintfBuffer[nCurrent]);}/************************************************************************//* UGKFPrintf() *//* *//* This is a little more complicated than just calling *//* fprintf() because of the variable arguments. Instead we *//* have to use vfprintf(). *//************************************************************************/int UGKFPrintf( FILE * fp, const char * pszFormat, ... ){ va_list args; int nReturn; va_start( args, pszFormat ); nReturn = vfprintf( fp, pszFormat, args ); va_end( args ); return( nReturn );}/********************************************************************** * UGKPrint() * * Print a StringList to fpOut. If fpOut==NULL, then output is sent * to stdout. * * Returns the number of lines printed. **********************************************************************/int UGKPrint(char **papszStrList, FILE *fpOut){ int nLines=0; if (fpOut == NULL) fpOut = stdout; if (papszStrList) { while(*papszStrList != NULL) { UGKFPrintf(fpOut, "%s\n", *papszStrList); nLines++; papszStrList++; } } return nLines;}/********************************************************************** * TokenizeString() * * Tokenizes a string and returns a StringList with one string for * each token. **********************************************************************/char **TokenizeString( const char *pszString ){ return TokenizeString2( pszString, " ", 0x0001 );}/************************************************************************//* TokenizeStringComplex() *//* *//* Obsolete tokenizing api. *//************************************************************************/char ** TokenizeStringComplex( const char * pszString, const char * pszDelimiters, int bHonourStrings, int bAllowEmptyTokens ){ int nFlags = 0; if( bHonourStrings ) nFlags |= 0x0001; if( bAllowEmptyTokens ) nFlags |= 0x0002; return TokenizeString2( pszString, pszDelimiters, nFlags );}/************************************************************************//* CSLTokenizeString2() *//* *//* The ultimate tokenizer? *//************************************************************************/char ** TokenizeString2( const char * pszString, const char * pszDelimiters, int nCSLTFlags ){ char **papszRetList = NULL; //用来存放一行的所有单词 int nRetMax = 0, nRetLen = 0; //nRetMax 能接收多少单词数,nRetLen为当前已接收多少单词 char *pszToken; //用来存放一个单词 int nTokenMax, nTokenLen; //nTokenLen表示一个字符在单词中位置,nTokenMax为默认一个单词最多字符数 int bHonourStrings = (nCSLTFlags & 0x0001); int bAllowEmptyTokens = (nCSLTFlags & 0x0002); pszToken = (char *) UGK_Calloc(10,1); nTokenMax = 10; while( pszString != NULL && *pszString != '\0' ) { int bInString = FALSE; nTokenLen = 0; /* Try to find the next delimeter, marking end of token */ for( ; *pszString != '\0'; pszString++ ) { /* End if this is a delimeter skip it and break. */ if( !bInString && strchr(pszDelimiters, *pszString) != NULL )//如果是引号里的空格则忽略 { pszString++; break; } //引号 /* If this is a quote, and we are honouring constant strings, then process the constant strings, with out delim but don't copy over the quotes */ if( bHonourStrings && *pszString == '"' ) { if( nCSLTFlags & 0x0004 )//$zgq { pszToken[nTokenLen] = *pszString; nTokenLen++; } if( bInString ) { bInString = FALSE; continue; } else { bInString = TRUE; continue; } } /* Within string constants we allow for escaped quotes, but in processing them we will unescape the quotes */ if( bInString && pszString[0] == '\\' && pszString[1] == '"' ) { if( nCSLTFlags & 0x0008 ) { pszToken[nTokenLen] = *pszString; nTokenLen++; } pszString++; } /* Within string constants a \\ sequence reduces to \ */ else if( bInString && pszString[0] == '\\' && pszString[1] == '\\' ) { if( nCSLTFlags & 0x0008 ) { pszToken[nTokenLen] = *pszString; nTokenLen++; } pszString++; } if( nTokenLen >= nTokenMax-3 ) { nTokenMax = nTokenMax * 2 + 10; pszToken = (char *) UGK_Realloc( pszToken, nTokenMax ); } pszToken[nTokenLen] = *pszString; nTokenLen++; } pszToken[nTokenLen] = '\0'; /* * If the last token is an empty token, then we have to catch * it now, otherwise we won't reenter the loop and it will be lost. */ if( (pszToken[0] != '\0' || bAllowEmptyTokens) || (*pszString == '\0' && bAllowEmptyTokens && strchr(pszDelimiters, *(pszString-1)) ) ) { if( nRetLen >= nRetMax - 1 ) { nRetMax = nRetMax * 2 + 10; papszRetList = (char **) UGK_Realloc(papszRetList, sizeof(char*) * nRetMax ); } papszRetList[nRetLen++] = UGKStrdup( pszToken ); papszRetList[nRetLen] = NULL; } } if( papszRetList == NULL ) papszRetList = (char **) UGK_Calloc(sizeof(char *),1); UGK_Free( pszToken ); return papszRetList;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -