公司出的练习题。只是放在CSDN上。不做讨论。 WordSort.h #ifndef WORDSORT_H_ #define WORDSORT_H_ typedef int WORDLIST_RESULT; #define WORDLIST_TRUE 1 #define WORDLIST_FALSE 0 #define WORDLIST_ERROR -1 #define WORD_CONTINUE_INDENT '-' #define CHAR_BUF_INIT_SIZE 512 #define CHAR_BUF_ENLARGE_SIZE 256 struct tagSubWordList_S { struct tagSubWordList_S *pstSubListNext; char *cWord; }; typedef struct tagSubWordList_S SubWordList_S; struct tagWordList_S { struct tagWordList_S *pstListNext; SubWordList_S stSubList; }; typedef struct tagWordList_S WordList_S; int BookMainTest(char *pcInputFileName, char *pcOutputFileName); WordList_S *SplitWord(const char *pcInputFileName); int WordListSort(WordList_S *const pstWordListHdr); int WordListOutput(WordList_S *const pstWordListHdr, const char *pcInputFileName); int WordListDestory(WordList_S *pstWordListHdr); int SubWordListNodeFree(WordList_S *const pstWordListNode); WordList_S *WordNodeAppend(WordList_S *pstWordList); char *EnlargeWordBuf(char *pcCurWordBuf, unsigned long *pulCurWordBufSize); WORDLIST_RESULT CharIsSeparator(const char cChar, const char *pcSeparList); #endif WordSort.cpp #include <stdio.h> #include <string.h> #include <malloc.h> #include "WordSort.h" const char acSeparChar[] = " 0123456789()[]!/'/""; int BookMainTest(char *pcInputFileName, char *pcOutputFileName) { WordList_S *pstWordListHdr = NULL; if ((NULL == pcInputFileName) || (NULL == pcOutputFileName)) { return -1; } pstWordListHdr = SplitWord(pcInputFileName); WordListSort(pstWordListHdr); WordListOutput(pstWordListHdr, pcOutputFileName); WordListDestory(pstWordListHdr); return 0; } /************************************************************************/ /* 从文件中拆分出单词 */ /************************************************************************/ WordList_S *SplitWord(const char *pcInputFileName) { FILE *fIn = NULL; int iInWord = 0; WordList_S *pstWordListTmpHdr = NULL; WordList_S *pstWordListCur = NULL; // 文件打开 fIn = fopen(pcInputFileName, "rt"); if (NULL == fIn) { printf("Input open err!/n"); return NULL; } // 数据读取 while ((iInWord = fgetc(fIn)) != EOF) { char cChar = (char)iInWord; if((WORDLIST_TRUE != CharIsSeparator(cChar, acSeparChar)) && ('/n' != cChar)) { // 正常情况 unsigned long ulWritePos = 0; unsigned long ulCurWordBufSize = 0; char cCharSecCur = '/0'; char cCharSecPre = '/0'; // 新建节点 if (NULL == pstWordListTmpHdr) { pstWordListTmpHdr = WordNodeAppend(NULL); pstWordListCur = pstWordListTmpHdr; } else { pstWordListCur = WordNodeAppend(pstWordListCur); } char *pcWordTmp = (char *)malloc(CHAR_BUF_INIT_SIZE * sizeof(char)); if (NULL == pcWordTmp) { printf("Malloc fail!/n"); return pstWordListTmpHdr; } memset((void *)pcWordTmp, 0, CHAR_BUF_INIT_SIZE); ulCurWordBufSize = CHAR_BUF_INIT_SIZE; pstWordListCur->stSubList.cWord = pcWordTmp; pstWordListCur->stSubList.pstSubListNext = NULL; cCharSecPre = cChar; *pcWordTmp = cChar; ++pcWordTmp; ++ulWritePos; // 第一个字符不会溢出,所以不判断ulWritePos>ulCurWordBufSize while ((iInWord = fgetc(fIn)) != EOF) { cCharSecCur = (char)iInWord; if (WORDLIST_TRUE == CharIsSeparator(cCharSecCur, acSeparChar)) { break; } if ((WORD_CONTINUE_INDENT == cCharSecPre) && ('/n' == cCharSecCur)) { --pcWordTmp; --ulWritePos; } else if ('/n' != cCharSecCur) { *pcWordTmp = cCharSecCur; ++pcWordTmp; ++ulWritePos; } else { // none } cCharSecPre = cCharSecCur; if (ulWritePos >= (ulCurWordBufSize - 1)) { pcWordTmp = EnlargeWordBuf(pcWordTmp, &ulCurWordBufSize); if (NULL == pcWordTmp) { return pstWordListTmpHdr; } } } // 读到结尾,退出 if (EOF == iInWord) { return pstWordListTmpHdr; } } } return pstWordListTmpHdr; } /************************************************************************/ /* 扩大buff的大小,会释放原来的buf, */ /* 修改pulCurWordBufSize指向对象为新的大小,返回新的buff指针 */ /************************************************************************/ char *EnlargeWordBuf(char *pcCurWordBuf, unsigned long *pulCurWordBufSize) { char *pcNewWordTmp = NULL; unsigned long ulCurWordBufSize = 0; if (NULL == pcCurWordBuf) { printf("Invalid argument!/n"); return NULL; } ulCurWordBufSize = *pulCurWordBufSize; pcNewWordTmp = (char *)malloc((ulCurWordBufSize + CHAR_BUF_ENLARGE_SIZE) * sizeof(char)); if (NULL == pcNewWordTmp) { printf("Malloc fail!/n"); return NULL; } memset((void *)pcNewWordTmp, 0, (ulCurWordBufSize + CHAR_BUF_ENLARGE_SIZE)); memcpy((void *)pcNewWordTmp, pcCurWordBuf, ulCurWordBufSize); free(pcCurWordBuf); pcCurWordBuf = NULL; *pulCurWordBufSize = ulCurWordBufSize + CHAR_BUF_ENLARGE_SIZE; return pcNewWordTmp; } int WordListSort(WordList_S *const pstWordListHdr) { int uiCmpRet = 0; if (NULL == pstWordListHdr) { printf("err para!/n"); return WORDLIST_ERROR; } WordList_S *pstWordListCur = pstWordListHdr; WordList_S *pstWordListTaler = pstWordListCur->pstListNext; WordList_S *pstWordListTalerFoll = pstWordListCur; while (NULL != pstWordListCur->pstListNext) { while (NULL != pstWordListTaler) { uiCmpRet = stricmp(pstWordListCur->stSubList.cWord, pstWordListTaler->stSubList.cWord); if (0 == uiCmpRet) { uiCmpRet = strcmp(pstWordListCur->stSubList.cWord, pstWordListTaler->stSubList.cWord); if (0 == uiCmpRet) {// 完全一样的WordList删掉 pstWordListTalerFoll->pstListNext = pstWordListTaler->pstListNext; pstWordListTalerFoll = pstWordListTalerFoll->pstListNext; SubWordListNodeFree(pstWordListTaler); free(pstWordListTaler); pstWordListTaler = NULL; if (NULL == pstWordListTalerFoll) { break; } if (NULL != pstWordListTalerFoll->pstListNext) { pstWordListTaler = pstWordListTalerFoll->pstListNext; } else { break; } } else { SubWordList_S *pstSubWordList = pstWordListCur->stSubList.pstSubListNext; while(NULL != pstSubWordList) { pstSubWordList = pstSubWordList->pstSubListNext; } pstSubWordList = (SubWordList_S *)malloc(sizeof(SubWordList_S)); memcpy((void *)pstSubWordList, (void *)&(pstWordListTaler->stSubList), sizeof(SubWordList_S)); pstWordListCur->stSubList.pstSubListNext = pstSubWordList; pstWordListTaler->stSubList.cWord = NULL; // 断开字符连接,已被pstSubWordList使用 pstWordListTalerFoll->pstListNext = pstWordListTaler->pstListNext; pstWordListTalerFoll = pstWordListTalerFoll->pstListNext; SubWordListNodeFree(pstWordListTaler); free(pstWordListTaler); pstWordListTaler = NULL; if (NULL == pstWordListTalerFoll) { break; } if (NULL != pstWordListTalerFoll->pstListNext) { pstWordListTaler = pstWordListTalerFoll->pstListNext; } else { break; } } } else if (uiCmpRet > 0) { // 大于则调换 WordList_S stWordListTmp; memset((void *)&stWordListTmp, 0, sizeof(WordList_S)); stWordListTmp.stSubList = pstWordListCur->stSubList; pstWordListCur->stSubList = pstWordListTaler->stSubList; pstWordListTaler->stSubList = stWordListTmp.stSubList; } else { // 不变 } pstWordListTaler = pstWordListTaler->pstListNext; pstWordListTalerFoll = pstWordListTalerFoll->pstListNext; } pstWordListCur = pstWordListCur->pstListNext; if (NULL == pstWordListCur) { break; } pstWordListTaler = pstWordListCur->pstListNext; pstWordListTalerFoll = pstWordListCur; } return WORDLIST_TRUE; } int WordListOutput(WordList_S *const pstWordListHdr, const char *pcInputFileName) { FILE *fout = NULL; WordList_S *pstWordListTrl = NULL; SubWordList_S *pstSubWordListTrl =NULL; if ((NULL == pstWordListHdr) || (NULL == pcInputFileName)) { printf("Can not open output file!"); return WORDLIST_FALSE; } fout = fopen(pcInputFileName, "wt"); if (NULL == fout) { printf("Can not open output file2!"); return WORDLIST_ERROR; } pstWordListTrl = pstWordListHdr; while (NULL != pstWordListTrl) { pstSubWordListTrl = &pstWordListTrl->stSubList; while (NULL != pstSubWordListTrl) { fprintf(fout, "%s", pstSubWordListTrl->cWord); pstSubWordListTrl = pstSubWordListTrl->pstSubListNext; if (NULL != pstSubWordListTrl) { fputc(' ', fout); } } fputc('/n', fout); pstWordListTrl = pstWordListTrl->pstListNext; } fclose(fout); return WORDLIST_TRUE; } int WordListDestory(WordList_S *pstWordListHdr) { WordList_S *pstWordListTmp = NULL; WordList_S *pstWordListTmpForWord = NULL; if (NULL == pstWordListHdr) { printf("WordListDestory para illegal!"); return WORDLIST_FALSE; } pstWordListTmp = pstWordListHdr; pstWordListTmpForWord = pstWordListHdr->pstListNext; while (NULL != pstWordListTmp) { SubWordListNodeFree(pstWordListTmp); free(pstWordListTmp); pstWordListTmp = NULL; if (NULL != pstWordListTmpForWord) { pstWordListTmp = pstWordListTmpForWord; pstWordListTmpForWord = pstWordListTmpForWord->pstListNext; } } return WORDLIST_TRUE; } int SubWordListNodeFree(WordList_S *const pstWordListNode) { SubWordList_S *pstSubWordListNode = NULL; SubWordList_S *pstSubWordList = NULL; SubWordList_S *pstSubWordListFoll = NULL; if (NULL == pstWordListNode) { return WORDLIST_FALSE; } pstSubWordListNode = &pstWordListNode->stSubList; pstSubWordList = pstSubWordListNode; if (NULL == pstSubWordList->pstSubListNext) { if (pstSubWordList->cWord != NULL) { free(pstSubWordList->cWord); pstSubWordList->cWord = NULL; } return WORDLIST_TRUE; } else { pstSubWordList = pstSubWordList->pstSubListNext; } while (1) { if (NULL == pstSubWordList->pstSubListNext) { return WORDLIST_TRUE; } else { pstSubWordListFoll = pstSubWordList; pstSubWordList = pstSubWordList->pstSubListNext; if (pstSubWordList->cWord != NULL) { free(pstSubWordListFoll->cWord); pstSubWordListFoll->cWord = NULL; } if (pstSubWordListFoll != NULL) { free(pstSubWordListFoll); pstSubWordListFoll = NULL; } } } return WORDLIST_TRUE; } /************************************************************************/ /*添加一个WordList_S节点到pstWordList后面,为空时新建 */ /************************************************************************/ WordList_S *WordNodeAppend(WordList_S *pstWordList) { WordList_S *pstWordListTmp = NULL; // 为空新建节点 if (NULL == pstWordList) { pstWordListTmp = (WordList_S *)malloc(sizeof(WordList_S)); if (NULL == pstWordListTmp) { printf("Node insert fail/n"); } memset((void *)pstWordListTmp, 0, sizeof(WordList_S)); return pstWordListTmp; } // 当前节点的下一节点已经存在 if (NULL != pstWordList->pstListNext) { printf("Append next is already exist!/n"); return pstWordList->pstListNext; } // 正常情况下在后面添加 pstWordListTmp = (WordList_S *)malloc(sizeof(WordList_S)); if (NULL == pstWordListTmp) { printf("Node insert fail/n"); } memset((void *)pstWordListTmp, 0, sizeof(WordList_S)); pstWordList->pstListNext = pstWordListTmp; return pstWordListTmp; } WORDLIST_RESULT CharIsSeparator(const char cChar, const char *pcSeparList) { unsigned char ucIdx = 0; unsigned char ucTotalSepar = strlen(pcSeparList); for (ucIdx = 0; ucIdx < ucTotalSepar; ++ucIdx) { if (cChar == *(pcSeparList + ucIdx)) { return WORDLIST_TRUE; } } return WORDLIST_FALSE; }