小说阅读器

来源:互联网 发布:inspection是什么软件 编辑:程序博客网 时间:2024/04/30 13:38

先把代码贴上吧,还有好多地方要完善,以后有时间再一点儿一点儿的完善吧

// 加这个全局变量为了避免一个bug,由于时间紧张,
//暂时就先这么来避免,有时间一定找到这个bug
bool g_bNovalNameNeedFind = true;

// 枚举小说内部信息的类型
typedef enum _tagInfoType
{
Noval_Name, // 小说名字
Noval_Author, // 小说作者
Noval_Set, // 小说集
Noval_Chapter, // 小说章
Noval_Text, // 小说正文
} eInfoType;

// 枚举显示界面的类型
typedef enum _tagUIType
{

}eUIType;

/**************************************************************
* 函数名字:my_strcmp
* 函数功能:比较两个字符串是否相等,相等则返回0,不相等则返回非零值
* 函数参数:const char *str1,要比较的第一个字符串,const char *str2,要
比较的第二个字符串
* 返回值 :相等返回 0, 不相等返回 非0值
**************************************************************/
int my_strcmp(const char *str1, const char *str2);
/**************************************************************
* 函数名字:my_strncmp
* 函数功能:比较两个字符串指定字符是否相等,相等则返回0,不相等则返回非零值
* 函数参数:const char *str1,要比较的第一个字符串,const char *str2,要
比较的第二个字符串,int maxNumber最多比较的字符的个数
* 返回值 :相等返回 0, 不相等返回 非0值
**************************************************************/
int my_strncmp(const char *str1, const char *str2, int maxNumber);
/**************************************************************
* 函数名字:my_strstr
* 函数功能:查找第二个字符串在第一个字符串中的位置
* 函数参数:char *str,第一个字符串 char *substr,第二个字符串
* 返回值 :第一个字符串的首地址
**************************************************************/
char *my_strstr(char *str, char *substr);
/**************************************************************
* 函数名字:showMainPage
* 函数功能:显示主页面
* 函数参数:无
* 返回值 :无
**************************************************************/
void showHomePage();
/**************************************************************
* 函数名字:acceptInput
* 函数功能:接受用户输入
* 函数参数:无
* 返回值 :无
**************************************************************/
void acceptInput();
/**************************************************************
* 函数名字:showCatLog
* 函数功能:显示目录
* 函数参数:无
* 返回值 :无
**************************************************************/
void showCatLog();
/**************************************************************
* 函数名字:printSameChars
* 函数功能:打印相同指定个数的字符到屏幕上
* 函数参数:c 要打印的字符,num 要打印的个数
* 返回值 :无
**************************************************************/
void printSameChars(char c, int num);
/**************************************************************
* 函数名字:printSameChars
* 函数功能:加载要阅读的文件,从而提取小说的名字和作者,分割章节等,如果
小说已存在,那么提示用户是否还要继续分割,根据用户的需求进行
相应的操作。
* 函数参数:无
* 返回值 :无
**************************************************************/
bool loadFile();
/**************************************************************
* 函数名字:splitFile
* 函数功能:分割文件,按照 小说名字-》小说作者-》集-》章-》.txt文件的形式
对原文件进行划分
* 函数参数:FILE *fp,要进行分解的文件指针
* 返回值 :成功返回 true,失败返回 false
**************************************************************/
bool splitFile(FILE *fp);
/**************************************************************
* 函数名字:determineType
* 函数功能:根据传过来的一行内容,确定这一行内容是什么类型的
* 函数参数:char *line_text,传过来的一行内容
* 返回值 :Noval_Name, // 小说名字
Noval_Author, // 小说作者
Noval_Set, // 小说集
Noval_Chapter, // 小说章
Noval_Text, // 小说正文
**************************************************************/
eInfoType determineType(char *line_text);
/**************************************************************
* 函数名字:isNovalName
* 函数功能:判断一行内容是否是小说名字
* 函数参数:const char *text_line一行内容的指针
* 返回值 :是小说的名字 返回true,不是小说的名字 返回false
**************************************************************/
bool isNovalName(char *text_line);
/**************************************************************
* 函数名字:isNovalAuthor
* 函数功能:判断一行内容是否是小说作者
* 函数参数:char *text_line一行内容的指针
* 返回值 :是小说的作者 返回true,不是小说的作者 返回false
**************************************************************/
bool isNovalAuthor(char *text_line);
/**************************************************************
* 函数名字:isNovalSet
* 函数功能:判断一行内容是否是小说的集
* 函数参数:char *text_line一行内容的指针
* 返回值 :是小说的集 返回true,不是小说的集 返回false
**************************************************************/
bool isNovalSet(char *text_line);
/**************************************************************
* 函数名字:isNovalChapter
* 函数功能:判断一行内容是否是小说的章
* 函数参数:char *text_line一行内容的指针
* 返回值 :是小说的章 返回true,不是小说的章 返回false
**************************************************************/
bool isNovalChapter(char *text_line);
/**************************************************************
* 函数名字:isNovalChapter
* 函数功能:判断一行内容是否是小说的章
* 函数参数:char *text_line一行内容的指针
* 返回值 :是小说的章 返回true,不是小说的章 返回false
**************************************************************/
bool isNumberChar(const char c);
/**************************************************************
* 函数名字:getNovalName
* 函数功能:获取小说的名字
* 函数参数:char *text_line一行内容的指针,char *novalName,输出参数,用于
保存得到小说名字
* 返回值 :得到小说的名字 返回true,没有得到小说的名字 返回false
**************************************************************/
bool getNovalName(char *text_line, char *novalName);
/**************************************************************
* 函数名字:getNovalAuthor
* 函数功能:获取小说的名字
* 函数参数:char *text_line一行内容的指针,char *novalName,输出参数,用于
保存得到小说作者
* 返回值 :得到小说的作者 返回true,没有得到小说的作者 返回false
**************************************************************/
bool getNovalAuthor(char *text_line, char *novalAuthor);
/**************************************************************
* 函数名字:getNovalSet
* 函数功能:获取小说的集名
* 函数参数:char *text_line一行内容的指针,char *novalSet,输出参数,用于
保存得到小说集名
* 返回值 :得到小说的集名 返回true,没有得到小说的集名 返回false
**************************************************************/
bool getNovalSet(char *text_line, char *novalSet);
/**************************************************************
* 函数名字:findNovalSet
* 函数功能:查找小说的集名
* 函数参数:char *text_line一行内容的指针,char *novalSet,输出参数,用于
保存得到小说集名
* 返回值 :得到小说的集名 返回true,没有得到小说的集名 返回false
**************************************************************/
bool cutOutNovalSet(char *text_line, char *novalChapter);
/**************************************************************
* 函数名字:getNovalChapter
* 函数功能:获取小说的章名
* 函数参数:char *text_line一行内容的指针,char *novalChapter,输出参数,用于
保存得到小说章名
* 返回值 :得到小说的章名 返回true,没有得到小说的章名 返回false
**************************************************************/
bool getNovalChapter(char *text_line, char *novalChapter);
/**************************************************************
* 函数名字:dirCat
* 函数功能:拼接目录
* 函数参数:const char *topLevelDir 上一级目录名字, const char *curDir 当
前目录名字,char *dstDir 拼接后的目录
* 返回值 :拼接成功 返回true,拼接失败 返回false
**************************************************************/
bool dirCat(const char *topLevelDir, const char *curDir, char *dstDir);
/**************************************************************
* 函数名字:dirCatFile
* 函数功能:拼接目录和文件
* 函数参数:const char *curDir 当前目录名字, const char *fileName 文件名
字, char *filePath 生成的文件路径
* 返回值 :拼接成功 返回true,拼接失败 返回false
**************************************************************/
bool dirCatFile(const char *curDir, const char *fileName, char *filePath);
/**************************************************************
* 函数名字:createDir
* 函数功能:创建目录
* 函数参数:const char *dirName 要创建的目录名字
* 返回值 :创建成功 返回true,创建失败 返回false
**************************************************************/
bool createDir(const char *dirName);

/*
需要分析一下,主要有几个界面,一个是主界面

*/

int main()
{
char cInput = 0;

// 加载小说文件if (loadFile()){

// // 显示主界面
// showHomePage();
// // 接受用户输入
// acceptInput();

    do    {        if (_kbhit())        {            cInput = _getch();        }        switch (cInput)        {        default:            break;        }    } while (cInput);}system("pause");return 0;

}

void showHomePage()
{
system(“cls”);
printSameChars(‘*’, 99);
printf(“\r\n\r\n”);
printSameChars(’ ‘, 33);
printf(“txt电子书阅读器 1.0版本”);
printf(“\r\n\r\n”);
printSameChars(’ ‘, 25);
printf(“请输入…\r\n\r\n”);
printSameChars(’ ‘, 25);
printf(“0. 退出\r\n\r\n”);
printSameChars(’ ‘, 25);
printf(“1. 显示目录\r\n\r\n”);
printSameChars(’ ‘, 25);
printf(“2. 开始阅读\r\n\r\n”);
printSameChars(’ ‘, 25);
printf(“3. 接着上次阅读\r\n\r\n”);
printSameChars(‘*’, 99);
printf(“\r\n\r\n”);
printSameChars(’ ‘, 20);
printf(“>>> “);
}

void acceptInput()
{
char c = 0;

while (true){    if (_kbhit())    {        c = _getch();        switch (c)        {        case '0':            // 退出            exit(0);            break;        case '1':            // 显示目录            printf("\r\n\r\n");            showCatLog();            break;        case '2':            // 开始阅读            // beginRead();            break;        case '3':            // 继续阅读            //continueRead();            break;        default:            break;        }    }}

}

void showCatLog()
{
bool bComplet = false;
char text_line[MAX_STR_LEN] = { 0 };
char novalSetName[MAX_STR_LEN] = { 0 };
char tmpNovalSetName[MAX_STR_LEN] = { 0 };
FILE *fp = NULL;
fp = fopen(“catlog.txt”, “r”);
if (fp)
{
while (true)
{
for (int i = 0; i < 3; )
{
if (NULL == fgets(text_line, MAX_STR_LEN, fp))
{
bComplet = true;
break;
}

            cutOutNovalSet(text_line, novalSetName);            if (my_strcmp(novalSetName, tmpNovalSetName))            {                printf("%-20s", novalSetName);                memcpy(tmpNovalSetName, novalSetName, MAX_STR_LEN);                i++;            }        }        if (bComplet)        {            break;        }        printf("\r\n\r\n");    }}

}

void printSameChars(char c, int num)
{
for (int i = 0; i < num; i++)
{
printf(“%c”, c);
}
}

char *my_strstr(char *str, char *substr)
{
while (*str != ‘\0’)
{
char *strTmp = str;
char *substrTmp = substr;

    while (*strTmp++ == *substrTmp++)    {        if (*substrTmp == '\0')        {            return str;        }    }    str++;}return NULL;

}

int my_strcmp(const char *str1, const char *str2)
{
while ((*str1 == *str2) && (*str1 != ‘\0’))
{
str1++;
str2++;
}

return *str1 < *str2 ? -1 : *str1 == *str2 ? 0 : 1;

}

int my_strncmp(const char *str1, const char *str2, int maxNumber)
{
int iCount = 0;
while ((*str1 == *str2) && (*str1 != ‘\0’))
{
iCount++;

    if (iCount == maxNumber)    {        break;    }    str1++;    str2++;}return *str1 < *str2 ? -1 : *str1 == *str2 ? 0 : 1;

}

bool loadFile()
{
bool bRet = false;
FILE *fp = NULL;
char szFileName[MAX_STR_LEN] = { 0 };

while (true){    printf("请输入要阅读的小说的文件名字...\r\n");    scanf_s("%s", szFileName, MAX_STR_LEN);    getchar();    fp = fopen(szFileName, "r");    if (fp)    {        // 对打开的文件进行文件分割,在分割的过程中,可能会发现小说的目录已经存在        // 那么我们会认为这个小说已经被加载过,应该就不需要重新加载了,但是为了保        // 险起见,还是需要让用户重新确认一遍是否需要重新加载        if (splitFile(fp))        {            printf("小说分割完成,是否进入阅读主界面?输入 yes 表示进入,其它表示退出...\r\n");            scanf_s("%s", szFileName, MAX_STR_LEN);            getchar();            if (!my_strcmp(szFileName, "yes"))            {                bRet = true;            }            break;        }    }    else    {        printf("您输入的文件名不存在,是否继续,退出请输入 yes, 继续请输入任意字符串...\r\n");        scanf_s("%s", szFileName, MAX_STR_LEN);        getchar();        if (!my_strcmp(szFileName, "yes"))        {            break;        }        else        {            continue;        }    }}return bRet;

}

bool splitFile(FILE *fp)
{
FILE *fpSplitFile = NULL;
eInfoType eRet = Noval_Text;
bool bRet = false;
char text_line[MAX_STR_LEN] = { 0 };
char strTmp[MAX_STR_LEN] = { 0 };
char dirNovalName[MAX_STR_LEN] = { 0 };
char dirAuthorName[MAX_STR_LEN] = { 0 };
char dirSetName[MAX_STR_LEN] = { 0 };
char fileName[MAX_STR_LEN] = { 0 };

if (fp){    while (true)    {        if (NULL == fgets(text_line, MAX_STR_LEN, fp))        {            break;        }        eRet = determineType(text_line);        switch (eRet)        {        case Noval_Name:        {            // 如果是小说的名字,那么就要以小说名字来创建一个存放小说文件的目录            if (getNovalName(text_line, dirNovalName))            {                if (!createDir(dirNovalName))                {                    // 创建目录失败,说明已经存在,暂时先认为不用再分割了                    bRet = true;                }            }        }            break;        case Noval_Author:        {            // 在创建小说作者目录的时候,必须要知道小说的名字,否则没有办法创建            // 可以用一个数组保存它们            if (getNovalAuthor(text_line, strTmp))            {                if (dirCat(dirNovalName, strTmp, dirAuthorName))                {                    createDir(dirAuthorName);                }            }        }            break;        case Noval_Set:        {            // 在创建小说集的目录的时候,肯定已经有了前面的小说的作者目录            if (getNovalSet(text_line, strTmp))            {                if (dirCat(dirAuthorName, strTmp, dirSetName))                {                    createDir(dirSetName);                }            }        }            break;        case Noval_Chapter:        {            // 在创建小说章的文件的时候,肯定已经有了前面的小说的集目录            if (getNovalChapter(text_line, strTmp))            {                if (fpSplitFile)                {                    fclose(fpSplitFile);                }                if (dirCatFile(dirSetName, strTmp, fileName))                {                    fpSplitFile = fopen(fileName, "a+");                }                FILE *fpCatlog = fopen("catlog.txt", "a+");                if (fpCatlog)                {                    fprintf(fpCatlog, "%s\r\n", fileName);                    fclose(fpCatlog);                }            }        }            break;        case Noval_Text:        {            // 在创建小说文件的时候,肯定已经有了前面的小说的集目录            if (fpSplitFile)            {                fprintf(fpSplitFile, "%s", text_line);            }        }            break;        default:            break;        }        if (bRet)        {            break;        }    }    if (fpSplitFile)    {        fclose(fpSplitFile);    }}return bRet;

}

eInfoType determineType(char *line_text)
{
// 默认情况下是小说的正文
eInfoType eRet = Noval_Text;

if (isNovalName(line_text)){    if (g_bNovalNameNeedFind)    {        g_bNovalNameNeedFind = false;        eRet = Noval_Name;    }}else if (isNovalAuthor(line_text)){    eRet = Noval_Author;}else if (isNovalSet(line_text)){    eRet = Noval_Set;}else if (isNovalChapter(line_text)){    eRet = Noval_Chapter;}return eRet;

}

bool isNovalName(char *text_line)
{
bool bRet = false;
char *strBegin = NULL;
char *strEnd = NULL;

strBegin = my_strstr(text_line, "《");if (strBegin){    strEnd = my_strstr(text_line, "》");    if (strEnd)    {        if (strBegin < strEnd + 7)        {            bRet = true;        }    }}return bRet;

}

bool isNovalAuthor(char *text_line)
{
bool bRet = false;

if (my_strstr(text_line, "作者:")){    bRet = true;}return bRet;

}

bool isNovalSet(char *text_line)
{
bool bRet = false;
char *strBegin = NULL;
char *strEnd = NULL;

strBegin = my_strstr(text_line, "第");if (strBegin){    strEnd = my_strstr(text_line, "集");    if (strEnd)    {        // 这里的判断可能还可以再优化        if ((strEnd > strBegin) && (strEnd < strBegin + 7))        {            bRet = true;        }    }}return bRet;

}

bool isNovalChapter(char *text_line)
{
bool bRet = false;
char *strBegin = NULL;

strBegin = my_strstr(text_line, "第");if (strBegin){    strBegin += 2;    while (isNumberChar(*strBegin))    {        strBegin++;    }    if (!my_strncmp(strBegin, "章", 2))    {        bRet = true;    }}return bRet;

}

bool isNumberChar(const char c)
{
bool bRet = false;

if ((c >= '0') && (c <= '9')){    bRet = true;}return bRet;

}

bool getNovalName(char *text_line, char *novalName)
{
bool bRet = false;
char *strBegin = NULL;
char *tmp = novalName;
int iCount = 0;

strBegin = my_strstr(text_line, "《");if (strBegin){    strBegin += 2;    while (*strBegin != '\n')    {        if (!my_strncmp(strBegin, "》", 2))        {            bRet = true;            break;        }        tmp[iCount] = *strBegin;        iCount++;        strBegin++;    }    tmp[iCount] = '\0';}return bRet;

}

bool getNovalAuthor(char *text_line, char *novalAuthor)
{
bool bRet = false;
char *strBegin = NULL;
char *tmp = novalAuthor;
int iCount = 0;

strBegin = my_strstr(text_line, "作者:");if (strBegin){    strBegin += 6;    while (*strBegin != '\n')    {        tmp[iCount] = *strBegin;        iCount++;        strBegin++;        bRet = true;    }    tmp[iCount] = '\0';}return bRet;

}

bool getNovalSet(char *text_line, char *novalSet)
{
bool bRet = false;
char *strBegin = text_line;
char *tmp = novalSet;
int iCount = 0;

if (strBegin){    while (*strBegin != '\n')    {        tmp[iCount++] = *strBegin++;    }    tmp[iCount] = '\0';    bRet = true;}return bRet;

}

bool cutOutNovalSet(char *text_line, char *novalSet)
{
bool bRet = false;
char *strBegin = NULL;
char *tmp = novalSet;
int iCount = 0;

strBegin = my_strstr(text_line, "第");if (strBegin){    while (*strBegin != '\\')    {        tmp[iCount] = *strBegin;        iCount++;        strBegin++;    }    tmp[iCount] = '\0';    bRet = true;}return bRet;

}

bool getNovalChapter(char *text_line, char *novalChapter)
{
bool bRet = false;
char *strBegin = text_line;
char *tmp = novalChapter;
int iCount = 0;

while (*strBegin != '\n'){    tmp[iCount++] = *strBegin++;    bRet = true;}tmp[iCount] = '\0';return bRet;

}

bool dirCat(const char *topLevelDir, const char *curDir, char *dstDir)
{
bool bRet = false;

if (topLevelDir && curDir){    char *tmp = dstDir;    int iCount = 0;    while (*topLevelDir)    {        tmp[iCount++] = *topLevelDir++;    }    tmp[iCount++] = '\\';    while (*curDir)    {        tmp[iCount++] = *curDir++;    }    tmp[iCount] = '\0';    bRet = true;}return bRet;

}

bool dirCatFile(const char *curDir, const char *fileName, char *filePath)
{
bool bRet = false;

if (curDir && curDir){    char *tmp = filePath;    int iCount = 0;    while (*curDir)    {        tmp[iCount++] = *curDir++;    }    tmp[iCount++] = '\\';    while (*fileName)    {        tmp[iCount++] = *fileName++;    }    tmp[iCount++] = '.';    tmp[iCount++] = 't';    tmp[iCount++] = 'x';    tmp[iCount++] = 't';    tmp[iCount] = '\0';    bRet = true;}return bRet;

}

bool createDir(const char *dirName)
{
bool bRet = false;

char mkdirName[64] = { 0 };sprintf(mkdirName, "md %s", dirName);if (!system(mkdirName)){    bRet = true;}return bRet;

}

1 0