C++:小说阅读器

C++:小说阅读器

这是我自己用 C++ & 减小代码长度用的批处理 做的一个用来看小说的程序,使用批处理主要是不太会C++Web编程,请求大佬们指教
现在这里还没加入什么小说,有什么比较好看的请各位推荐

文章目录

  • C++:小说阅读器
  • 说明
    • 下载
  • 更新日志
  • 代码
    • 1. 打包版本
    • 2. 最新代码
      • main.exe
      • novel.exe
  • 制作:

说明

这是用的我自己的服务器,里面的小说需要自己处理才可使用,并且程序会自动更新,更新日志会在这里发布。

下载

更新日志

2020.8.21前的更新日志忘了

  • 2020.8.21
    添加了学生机功能
    版本&版本号:1.0.6-200821 8
  • 2020.9.12
    修改了更新的批处理,将主界面修改为管理员方式运行
    版本&版本号:1.0.7-200912 9

代码

1. 打包版本

简化代码,只留下更新部分

/*
Made In Aichi @2019-2020
Aichi主站: http://aichistudio.space
Aichi百科: http://baike.aichistudio.space

版权归 爱知工作室 所有
*/
//头文件引入
#include
#include
#include
#include
#define _for(i,a,b) for(int i=a;i
//标准输出句柄
#define handle GetStdHandle(STD_OUTPUT_HANDLE)
//版本号,因为是缩减版,所以将版本号设为-1,这样一定会启动更新
#define EDITION_ID -1 
#define EDITION 0.0.0-20190000
using namespace std;
//隐藏与显示光标函数
void cursor(bool a){
     
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);
	CursorInfo.bVisible = a;
	SetConsoleCursorInfo(handle, &CursorInfo);
}
//更新函数
void update(){
     
	system("cls");//清屏
	printf("检查更新...");
	/*
	Windows有个程序叫bitsadmin,Windows的许多更新就是由它完成的,
	因为不太会C++Web编程所以使用这个来下载东西
	*/
	system("bitsadmin /transfer 检查更新 http://aichistudio.space/novel/api/edition %cd%\\edition.txt");//下载最新版本信息
	//读取最新版本号
	ifstream update_input("edition.txt");
	int editionid;
	update_input>>editionid;
	if(editionid>EDITION_ID){
     //如果最新版本号大于目前版本,则进行更新
		system("start update");
		exit(0);
	}
}
//初始化函数
void init(){
     
	system("mode con cols=90 lines=30");//初始化窗口大小
	ofstream update_code("update.bat");//输出更新程序
	//接下来就是批处理了,不做讲解
	update_code<<"@echo off\n"\
				<<"cd /d %~dp0"\
				<<"%1 start \"\" mshta vbscript:createobject(\"shell.application\").shellexecute(\"\"\"%~0\"\"\",\"::\",,\"runas\",1)(window.close)&exit"\
				<<"bitsadmin /transfer 检查更新 http://aichistudio.space/novel/api/update_list %cd%\\update_list.txt\n"\
				<<"for /f \"delims=\" %%i in (update_list.txt) do bitsadmin /transfer 更新文件%%i http://aichistudio.space/static/file/novel/%%i %cd%\\%%i\n"\
				<<"start main.exe\n"\
				<<"exit";
}
//主函数
int main(){
     
	init();
	update();
	return 0;
}

2. 最新代码

  • main.exe

/*
Made In Aichi @2019-2020
Aichi主站: http://aichistudio.space
Aichi百科: http://baike.aichistudio.space

版权归 爱知工作室 所有
*/
#include
#include
#include
#include
#define _for(i,a,b) for(int i=a;i
#define handle GetStdHandle(STD_OUTPUT_HANDLE)
#define EDITION_ID 9 
#define EDITION 1.0.7-200912
using namespace std;
void main_interface();
void cursor(bool a){
     
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);
	CursorInfo.bVisible = a;
	SetConsoleCursorInfo(handle, &CursorInfo);
}
void update(){
     
	system("cls&del edition.txt");
	system("title 检查更新...");//设置标题
	printf("检查更新...");
	system("bitsadmin /transfer 检查更新 http://aichistudio.space/novel/api/edition %cd%\\edition.txt");
	ifstream update_input("edition.txt");
	int editionid;
	update_input>>editionid;
	if(editionid>EDITION_ID){
     
		system("start update");
		exit(0);
	}
}
//本地小说
void local_novels(){
     
	system("cls&title 本地小说");//设置标题
	system("dir %cd%\\novels\\* /B > list.txt");//用批处理获得已有小说列表
	char novels[500][200]={
     };//定义小说名称数组
	int n=0;//小说数量
	//读取
	ifstream local_novel_list("list.txt");
	while(local_novel_list.getline(novels[n++],200));
	if(strlen(novels[0])==0){
     //如果没有读取到小说
		printf("没有小说");
		system("pause");
		return;
	}
	n--;//最后一个名称为空,所以要减回来
	/*
	模拟while
	W:
	...
	goto W;
	可以理解为while(1)
	*/
	W:
	system("cls");//清屏
	//打印屏幕
	printf("输入0来返回\n");
	_for(i,0,n){
     
		printf("%d. %s\n",i+1,novels[i]);
	}
	printf("id: ");
	//用户输入id
	int k=0;
	scanf("%d",&k);
	if(k==0)return;//id==0则返回主界面
	if(k>0&&k<=n){
     //如果id在列表内
		freopen("novel.txt","w",stdout);//对novel.exe更新正在看的小说
		printf(novels[k-1]);//选中的小说名称
		system("start novel.exe");//启动
		exit(0);
	}else{
     //否则
		printf("id错误!");
		Sleep(2000);//等待2s
		goto W;//返回到 W:
	}
}
//下载新的
void download_novels(){
     
	system("cls");
	system("title 获取小说列表...");
	system("bitsadmin /transfer 获取小说列表 http://aichistudio.space/novel/api/list %cd%\\weblist.txt");//批处理获得已有的小说列表
	//读取
	char novels[500][200]={
     };
	int n=0;
	ifstream local_novel_list("weblist.txt");
	while(local_novel_list.getline(novels[n++],200));
	n--;
	W:
	system("cls&title 下载新小说");
	//打印
	_for(i,0,n){
     
		printf("%d. %s\n",i+1,novels[i]);
	}
	printf("id: ");
	int k=0;
	scanf("%d",&k);
	if(k>0&&k<=n){
     //id在列表内
		//执行下载,利用string来生成批处理代码
		string download_code="download ";
		download_code.append(novels[k-1]);
		system(download_code.data());
		return;//返回主界面
	}else{
     //否则
		printf("id错误!");
		Sleep(2000);
		goto W; 
	}
}
//主界面
void main_interface(){
     
	R: //外层循环
	system("cls&title 主界面");
	//打印界面
	printf("1.本地小说    2.下载新的");
	W: //不会重新打印界面
	char k=getch();//键盘读取
	if(k=='1')local_novels();//按下 1 
	else if(k=='2')download_novels();//按下 2
	else goto W;//都不是这返回,不重新打印界面
	goto R;//执行完则重新打印
}
//初始化
void init(){
     
	system("mode con cols=90 lines=30");
	cursor(0);
	system("md novels");
	ofstream update_code("update.bat");
	update_code<<"@echo off\n"\
				<<"cd /d %~dp0"\
				<<"%1 start \"\" mshta vbscript:createobject(\"shell.application\").shellexecute(\"\"\"%~0\"\"\",\"::\",,\"runas\",1)(window.close)&exit"\
				<<"bitsadmin /transfer 检查更新 http://aichistudio.space/novel/api/update_list %cd%\\update_list.txt\n"\
				<<"for /f \"delims=\" %%i in (update_list.txt) do bitsadmin /transfer 更新文件%%i http://aichistudio.space/static/file/novel/%%i %cd%\\%%i\n"\
				<<"start main.exe\n"\
				<<"exit";
	//下载小说的批处理
	ofstream download_code("download.bat");
	download_code<<"bitsadmin /transfer 下载《%1》 http://aichistudio.space/static/file/novel/%1.txt %cd%\\novels\\%1";
}
VOID ManagerRun(LPCSTR exe,LPCSTR param,INT nShow=SW_SHOW){
     //以管理员状态运行 
 	SHELLEXECUTEINFO ShExecInfo; 
 	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);  
 	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS ;  
 	ShExecInfo.hwnd = NULL;  
 	ShExecInfo.lpVerb = "runas";  
 	ShExecInfo.lpFile = exe; 
 	ShExecInfo.lpParameters = param;   
 	ShExecInfo.lpDirectory = NULL;  
 	ShExecInfo.nShow = nShow;  
 	ShExecInfo.hInstApp = NULL;   
 	BOOL ret = ShellExecuteEx(&ShExecInfo);  
 	CloseHandle(ShExecInfo.hProcess);
 	return;
}
int main(int argc,char *argv[]){
     
    if(argc==1){
     
    	ShowWindow(GetConsoleWindow(),SW_HIDE);
       	ManagerRun(argv[0],"2");
       	return 1;
    }else if(argc==2){
     
		init();
		update();
		main_interface();
	}
	return 0;
}
  • novel.exe

/*
Made In Aichi @2019-2020
Aichi主站: http://aichistudio.space
Aichi百科: http://baike.aichistudio.space

版权归 爱知工作室 所有
*/
#include
#include
#include
#define _for(i,a,b) for(int i=a;i
#define handle GetStdHandle(STD_OUTPUT_HANDLE)
using namespace std;
char name[500];
int id,line,n;
bool SCM;//学生机模式bool值
string novels[100000];//小说内容
ifstream novel;//读取文件的变量
HWND hWnd=GetForegroundWindow();//窗口句柄
void gotoxy(double x,int y){
     //光标定位函数
	COORD pos;
	pos.X=2*x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void cursor(bool a){
     
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);
	CursorInfo.bVisible = a;
	SetConsoleCursorInfo(handle, &CursorInfo);
}
void init(){
     //初始化
	system("mode con cols=90 lines=9999");
	cursor(0);
}
void input(){
     //读取数据
	{
     //读取阅读的小说名称
		ifstream tttt("novel.txt");
		tttt>>name;
	}
	{
     //读取已看到的章节
		ifstream temp(name);
		temp>>id;
	}
	//打开小说
	string code="novels/";
	code.append(name);
	novel.open(code.data());
	_for(i,0,id+1){
     //读取到正在阅读的章节
		getline(novel,novels[i],'|');//章与章之间以“|”分割
	}
	n=id;//最大读取到的章节数
	string title_code="title ";//用string生成标题指令
	title_code.append(name);
	title_code.append("(按下 Q 启动学生机模式)");
	system(title_code.data());
}
void keep(){
     //保存阅读进度
	ofstream keeping(name);
	keeping<<id;
}
void read(){
     //阅读
	W: //外层循环
	system("cls");
	//打印当前小说章节
	cout<<novels[id];
	gotoxy(0,0);//定位光标到第一行
	line=0;//阅读到的函数
	while(1){
     //循环读取键盘事件
		cursor(0);//隐藏光标
		if(_kbhit()){
     //有键盘被按下
			char k=_getch();//获取键值
			if(k==72||k=='w'||k=='W'){
     //按下 ↑ 或 W
				if(line>=5){
     //如果阅读的行>=5则往上5行
					line-=5;
					gotoxy(0,line);
				}
			}
			if(k==80||k=='s'||k=='S'){
     //按下 ↓ 或 S
				line+=5;//往下5行
				gotoxy(0,line);
			}
			if(k==75||k=='a'||k=='A'){
     //按下 ← 或 A
				if(id>0){
     //不是第一章
					id--;//往前一张
					keep();//储存进度
					goto W;//返回,并重新打印
				}
			}
			if(k==77||k=='d'||k=='D'){
     //按下 → 或 D
				id++;//章节到下一张
				if(id>n){
     //如果超出已读取的范围,则读取新的一章
					n=id;
					getline(novel,novels[id],'|');
				}
				keep();//储存进度
				goto W;
			}
			if(k=='q'||k=='Q'){
     //如果按下 Q
				if(!SCM){
     //没有启动学生机模式
					string title_code="title ";
					title_code.append(name);
					title_code.append("_学生机模式(按下Q来关闭)");
					system(title_code.data());//设置新标题
				}else{
     //否则
					string title_code="title ";
					title_code.append(name);
					title_code.append("(按下 Q 启动学生机模式)");
					system(title_code.data());
					//取消置顶
					SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
				}
				SCM=!SCM;
			}
		}
		if(SCM)//如果启动了学生机模式,则循环置顶
			SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
		if(!SCM)Sleep(10);//没有启动学生机模式才有等待,启动学生机模式就不等待
	}
}
int main(){
     
	init();
	input();
	read();
	return 0;
}

制作:

From AichiStudio爱知工作室,
网站:http://aichistudio.space
QQ交流群:1032103456

你可能感兴趣的:(自制应用)