📄 readline.c
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include "util.h"#include "ReadLine.h"/* Pass in a pointer to a token list. Is freed and then set to null */voidFreeTokens(INOUT char ***TokensPtr){ assert(*TokensPtr); assert(**TokensPtr); free(**TokensPtr); /* Free the string data */ free(*TokensPtr); /* Free token list */ *TokensPtr = NULL; /* Invalidate pointer since mem is gone */}/* Returns number of tokens in list. Zero if null list */intCountTokens(IN char **Tokens){ int count = 0; if(NULL == Tokens) { return 0; }; while(Tokens[count]) { ++count; }; return count;}/* Reads in a single line from file, splits into tokens and allocates * a list of tokens. Returns the an array of character arrays with the * final item being marked by an empty string. * Returns NULL on EOF * NB: Token list is does as two allocations, one for pointer list * and one for character array. Free what pointer points to and then * free the pointer itself */char **ReadLineTokens(INOUT FILE * InFile, INOUT int *LineNum){ enum { BUFFSIZE = 65536 }; /* This is much more than enough */ char Buffer[BUFFSIZE]; /* Must match BUFFSIZE */ char *Res; char *Last; char *Cur; char *Dst; char **Tokens; int TokenCount; int Len; int CurToken; boolean InToken; do { /* Read the string */ Res = fgets(Buffer, BUFFSIZE, InFile); if(NULL == Res) { if(feof(InFile)) { return NULL; /* Return NULL on EOF */ } else { printf(ERRTAG "Unexpected error reading file\n"); exit(1); } } ++(*LineNum); /* Strip newline if any */ Last = Buffer + strlen(Buffer); if((Last > Buffer) && ('\n' == Last[-1])) { --Last; } if((Last > Buffer) && ('\r' == Last[-1])) { --Last; } /* Handle continued lines */ while((Last > Buffer) && ('\\' == Last[-1])) { /* Strip off the backslash */ --Last; /* Read next line by giving pointer to null-char as start for next */ Res = fgets(Last, (BUFFSIZE - (Last - Buffer)), InFile); if(NULL == Res) { if(feof(InFile)) { return NULL; /* Return NULL on EOF */ } else { printf(ERRTAG "Unexpected error reading file\n"); exit(1); } } ++(*LineNum); /* Strip newline */ Last = Buffer + strlen(Buffer); if((Last > Buffer) && ('\n' == Last[-1])) { --Last; } if((Last > Buffer) && ('\r' == Last[-1])) { --Last; } } /* Strip comment if any */ Cur = Buffer; while(Cur < Last) { if('#' == *Cur) { Last = Cur; break; } ++Cur; } /* Count tokens and find size */ assert(Last < (Buffer + BUFFSIZE)); Len = 0; TokenCount = 0; Cur = Buffer; InToken = FALSE; while(Cur < Last) { if(InToken) { if((' ' == *Cur) || ('\t' == *Cur)) { InToken = FALSE; } else { ++Len; } } else { if((' ' != *Cur) && ('\t' != *Cur)) { ++TokenCount; ++Len; InToken = TRUE; } } ++Cur; /* Advance pointer */ } } while(0 == TokenCount); /* Find the size of mem to alloc. Use a contiguous block so is * easy to deallocate */ Len = (sizeof(char) * Len) + /* Length of actual data */ (sizeof(char) * TokenCount); /* Null terminators */ /* Alloc the pointer list and data list. Count the final * empty string we will use as list terminator */ Tokens = (char **)my_malloc(sizeof(char *) * (TokenCount + 1)); *Tokens = (char *)my_malloc(sizeof(char) * Len); /* Copy tokens to result */ Cur = Buffer; Dst = *Tokens; InToken = FALSE; CurToken = 0; while(Cur < Last) { if(InToken) { if((' ' == *Cur) || ('\t' == *Cur)) { InToken = FALSE; *Dst = '\0'; /* Null term token */ ++Dst; ++CurToken; } else { *Dst = *Cur; /* Copy char */ ++Dst; } } else { if((' ' != *Cur) && ('\t' != *Cur)) { Tokens[CurToken] = Dst; /* Set token start pointer */ *Dst = *Cur; /* Copy char */ ++Dst; InToken = TRUE; } } ++Cur; /* Advance pointer */ } if(InToken) { *Dst = '\0'; /* Null term final token */ ++Dst; ++CurToken; } assert(CurToken == TokenCount); /* Set the final empty string entry */ Tokens[CurToken] = NULL; /* Return the string list */ return Tokens;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -