当c++爱上了vbs—让你的c++会说话

当c++爱上了vbs—让你的c++会说话

在开始这篇文章之前,我们先来讲一款在windows上且具有黑科技的编程语言:vbs
百度上vbs的简单描述

是的,在百度搜索中,对vbs的介绍就是这么简单。
然而其实,vbs的代码难度比这还要简单。
但vbs并不能算是今天的主题
那么,现在在知道了vbs是啥的时候,再来看看这八卦一般的标题,你大概懂我们要是干啥了吧
没错,今天我们要在c++中调用vbs
首先我们来认识一下今天我们要用到的函数
1.fopen()
这个函数应该众人皆知了,是c++标准库中除了freopen最常用的文件处理函数
主要功能是写入读取和创建,然后这里放一张表格供参考:
在这里插入图片描述

2.system()
这里的话可以把c++的控制台想象成cmd的窗口,然后在system中的代码就是你的批处理代码,但如果你真的了解批处理的话,就知道如果直接在cmd的窗口输入文件名(或路径)的话他会打开你要他打开的文件,这个有趣的功能让我们的c++有了一扇通向编译器外世界的窗户。

竟然函数都了解了,现在是时候来进行speak函数的理论推理了
首先我们知道vbs的说话代码的写法(问度娘),然后我们现在想象c++是我们人类,我们是怎么让vbs说话的。这时就要用到我说的第一个函数fopen了。
通过查表我们能看出,fopen的函数模式中w可以创建并写入文件,但写入的比一定是.out或.in的文件,所以只要创建一个vbs文件并且在这个文件中输入vbs说话的代码,就模拟了人新建文件和右键编辑的功能,然后就是打开它了,还记得我们还有那个函数没用到吗?对,system函数,system函数在这里的作用主要就是模拟人的双击,但是系统还要完成一项功能就是在说完话清除痕迹,所以就要用到vbs中删除自己的代码,然后这里又要讲一个关于vbs的有趣的特性:“当以运行一个vbs的时候,删除也解决不了他要运行自己的兴趣”vbs在运行时我们可以简单地理解为他把自己的代码先运送给了编译器,然后就不管文件的事了,也就可以简单地理解为你运行了exe文件时把cpp文件删除也不会影响exe的运行,所以如果想要vbs文件在你电脑上呆的时间尽可能地小,就只需要在代码的第一行删除自己,也不会影响到代码的运行。
现在理论实现,实践开始
(这里要注意一点,在写代码的时候,c++读取文件的时候system是打不开文件的因为文件正在使用,所以需要把fclose写在system前面)

#include<bits/stdc++.h>
using namespace std;
void speak(string the_world_say)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\nCreateObject(\"SAPI.SpVoice\").Speak\""+the_world_say+"\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%speak_c++.vbs");
	return;
}
int main()
{
	speak("哦我成功了");
	return 0;
}

这里的话中间那一条长长的代码实现的是vbs的程序,然后再讲两个技巧,一个是在第7行的.c_str()是string类型转char指针的一种最简单的方法,这里fopen的输入格式是char指针但string类型有一个好处,也就是另外一个技巧:+这个应该很多人都知道,例如第6行最后,可以直接快速的连接两个字符串。
现在快去你的电脑上试试吧,只要不出意外所有电脑都做得到!
什么?你以为这就完了?
不不,当然不是,你看我像是那种遇到问题蜻蜓点水就能满足的人吗
那么,我们的问题又来了:那就是在系统说话的时候,你不能进行其他计算!
这又要怪到帮了我们大忙的system身上了。
Systetm是一个对人很严格的函数,当我们让他运行其他程序的时候,只有这个程序运行完,才能进行下一条语句,也就是说,如果你让他说上5分钟的演讲,这宝贵的五分钟他将不能进行其他运算,这能忍?
这时候,我们又请出了我们的vbs大佬,那么,现在我们实现的就是一个run的代码,同样的,我们来先进行理论研究:
首先我们分析过了为什么不能同时说话同时运算的问题所在,那么解决起来不就简单了,不就,有手就行?
如果直接打开不行,就让他间接打开!
首先经过查询c++除了system之外没有一个能打开其他文件的指令了,那么我们就从system函数上面进行分析,vbs中运行其他程序的代码为createobject(“wscript.shell”).Exec”文件名”,这个程序可以在其他程序没运行完前继续下一行代码,如果后面没有其他语句的话就是在打开其他文件后直接关闭自己,没有所谓的“等待时间”,所以用system打开这个vbs文件来打开其他vbs文件就可以在运行vbs的同时继续进行其他运算,正如俗话所说“已v治v必能治v与无形之中”
理论存在,开始实践

#include<bits/stdc++.h>
using namespace std;
void speak(string the_world_say)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\nCreateObject(\"SAPI.SpVoice\").Speak\""+the_world_say+"\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}
int main()
{
	speak("哦我成功了");
	return 0;
}//有手就行

好的这里我们就迎来了speak函数的2.0版本
什么?你以为这就结束了?
不不,当然不是!
仔细读一下这篇文章的主标题
你以为这篇文章只有“说话”这么简单?
不不,当然不是!
为了实现这次我们的终极目标
我们首先要写一个叫做vbs()的函数
这很简单,经过上面的推理
有手就行!


void vbs(string vbs_code_input)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	fputs(vbs_code_input.c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}

主要原理和上面一样,通过创建vbs和打开他来实现
竟然函数都出来了
那那些当年翻遍百度都没找到的功能不也就这?
1.msgbox(手写)

void vbs(string vbs_code_input)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	fputs(vbs_code_input.c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}
void msgbox(string a)
{
	vbs("CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\nmsgbox\""+a+"\"");
	return;
}

2.搞人

on error resume next
dim WSHshellA
set WSHshellA = wscript.createobject("wscript.shell")
WSHshellA.run "cmd.exe /c shutdown -r -t 120 -c ""说你是猪,快说你是猪 不说120秒关你机,不信,试试···"" ",0 ,true
dim a
do while(a <> "我是猪")
a = inputbox ("说你是猪,就不关机,快撒,说 ""我是猪"" ","说不说","不说",8000,7000)
msgbox chr(13) + chr(13) + chr(13) + a,0,"MsgBox"
loop
msgbox chr(13) + chr(13) + chr(13) + "早说就行了嘛"
dim WSHshell
set WSHshell = wscript.createobject("wscript.shell")
WSHshell.run "cmd.exe /c shutdown -a",0 ,true
msgbox chr(13) + chr(13) + chr(13) + "嘿嘿 真是猪! 气死你 小样!!"

这个是一个vbs代码,以前玩过的,表示效果很好
但是这里并不是想让大家用它去整人,只是想当作参考
例如对话框判断和关机等等功能都可以用vbs简单的实现
而c++身为一个超级复杂又超级简单的语言如果结合了其它语言的精华
岂不妙哉?
什么?你以为这就结束了。
竟然有了函数,我们为何不制作一个可以供童鞋们使用的头文件呢?
vbs.h


#include<bits/stdc++.h>
using namespace std;
void speak(string the_world_say)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\nCreateObject(\"SAPI.SpVoice\").Speak\""+the_world_say+"\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}
void vbs(string vbs_code_input)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	fputs(vbs_code_input.c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}
void msgbox(string a)
{
	vbs("CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\nmsgbox\""+a+"\"");
	return;
}

然后以后就#include就可以了
根据原理还可以研究出许多有趣的内容
什么?你以为这就结束了?
对,这里真的就结束了。
C++与vbs的爱情故事还在发展
究竟他们之间又会进化出什么爱情的火花
还得靠我们好好研究一番
就像是用刚刚的vbs函数其实可以写出一个基于c++的vbs编译器
那么为什么我没有做呢?
因为我们还没有真正结束啊!
是时候说一下写编译器的难点了,当你要编译的时候,一定要有一个特殊的按键用来编译代码,但是vbs按键使用率太高了,我还想过要每写一行就弹出对话框:要编译吗?但实在太恶心了。
然后我的目标转向了键盘的右上角
"`"
然后这个编译器就出现了

#include<bits/stdc++.h>
using namespace std;
void vbs(string vbs_code_input)
{
	FILE* fp=fopen("%2%speak_c++.vbs","w");
	fputs(((string)"CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\n"+vbs_code_input).c_str(),fp);
	fclose(fp);
	fp=fopen("%2%runing_speak_c++.vbs","w");
	string the_vbs_code="CreateObject(\"Scripting.FileSystemObject\").DeleteFile(WScript.ScriptName)\ncreateobject(\"wscript.shell\").run\"%2%speak_c++.vbs\"";
	fputs(the_vbs_code.c_str(),fp);
	fclose(fp);
	system("%2%runing_speak_c++.vbs");
	return;
}
string the_final_code,the_input_code,zero_string;
char input_;
int main()
{
	while(1)
	{
		input_=getchar();
		if(input_=='`'){vbs(the_final_code);the_final_code=zero_string;}
		else the_final_code=the_final_code+input_;
	}
	return 0;
}

啊对就是这么简单。
因为没做保存和退格
然后接下来是食用方法:
先输入vbs代码
然后输入英文的`后回车
然后他自己就运行了
是不是很神奇?

以后可能会做不开源的图形库版本。
然后你们就快乐的使用就行了!
啊好了同学们学会了吗?
学会了何不点一个大大的喜欢呢[狗头]
如果有更好的函数(基于vbs())为何不进行讨论交流,让更多人看到你优秀的头像哪?[黄金24k狗头保命]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值