C++:小说阅读器

C++:小说阅读器

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

说明

这是用的我自己的服务器,里面的小说需要自己处理才可使用,并且程序会自动更新,更新日志会在这里发布。
因为C++访问网络过于麻烦,现在正考虑将语言换成Python

下载

抱歉,之前打包版出现了小问题,现已解决

更新日志

2020.8.21前的更新日志忘了

  • 2020.8.21
    添加了学生机功能
    版本&版本号:1.0.6-200821 8
  • 2020.9.12
    修改了更新的批处理,将主界面修改为管理员方式运行
    版本&版本号:1.0.7-200912 9
  • 2021.7.28 更换服务器
    不做版本更新,因为之前的域名无法解析,请重新安装最新版本

代码

1. 打包版本

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

/*
Made In Sakuyark @2021
Sakuyark: https://sakuyark.com
Copyright © 2021 Sakuyark
*/
//头文件引入
#include<bits/stdc++.h>
#include<windows.h>
#include<string>
#include<conio.h>
#define _for(i,a,b) for(int i=a;i<b;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 检查更新 https://sakuyark.com/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"\
				<<"set mycd=%cd%\n"\
				<<"cd /d %~dp0\n"\
				<<"%1 start \"\" mshta vbscript:createobject(\"shell.application\").shellexecute(\"\"\"%~0\"\"\",\"::\",,\"runas\",1)(window.close)&exit\n"\
				<<"bitsadmin /transfer 检查更新 https://sakuyark.com/novel/api/update_list %mycd%\\update_list.txt\n"\
				<<"for /f \"delims=\" %%i in (update_list.txt) do bitsadmin /transfer 更新文件%%i http://aichistudio.space/static/file/novel/%%i %mycd%\\%%i\n"\
				<<"start main.exe\n"\
				<<"exit";
}
//主函数
int main(){
	init();
	update();
	return 0;
}

2. 最新代码

  • main.exe

/*
Made In Sakuyark @2021
Sakuyark: https://sakuyark.com
Copyright © 2021 Sakuyark
*/
#include<bits/stdc++.h>
#include<windows.h>
#include<string>
#include<conio.h>
#define _for(i,a,b) for(int i=a;i<b;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 检查更新 https://sakuyark.com/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 获取小说列表 https://sakuyark.com/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"\
				<<"set mycd=%cd%\n"\
				<<"cd /d %~dp0\n"\
				<<"%1 start \"\" mshta vbscript:createobject(\"shell.application\").shellexecute(\"\"\"%~0\"\"\",\"::\",,\"runas\",1)(window.close)&exit\n"\
				<<"bitsadmin /transfer 检查更新 https://sakuyark.com/novel/api/update_list %mycd%\\update_list.txt\n"\
				<<"for /f \"delims=\" %%i in (update_list.txt) do bitsadmin /transfer 更新文件%%i https://sakuyark.com/static/file/novel/%%i %mycd%\\%%i\n"\
				<<"start main.exe\n"\
				<<"exit";
	//下载小说的批处理
	ofstream download_code("download.bat");
	download_code<<"bitsadmin /transfer 下载《%1》 https://sakuyark.com/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 Sakuyark @2021
Sakuyark: https://sakuyark.com
Copyright © 2021 Sakuyark
*/
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
#define _for(i,a,b) for(int i=a;i<b;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 Sakuyark,
网站:https://sakuyark.com
QQ交流群:1032103456

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值