小说阅读器

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

// 加这个全局变量为了避免一个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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值