编写可以打开文本文件并打乱在该文件中所找到的单词顺序的vbs脚本_vbs

问:
您好,脚本专家!我女儿有一种闪卡式程序,它能够获取文本文件中的单词列表。我如何编写一个脚本,使其能够打开该文件并自动打乱单词列表的顺序呢?
-- SN
答:
您好,SN。您知道,大多数情况下,我们尽力使此专栏关注实际的系统管理任务:我们告诉您如何设置默认打印机、如何禁用服务以及如何映射网络驱动器。不过,有时我们也愿意处理那种听起来就很有趣的问题,而最终的结果有多大用处我们是不会去考虑的。系统管理员通常需要打乱文本文件中单词列表的顺序吗?可能不需要。但是,若是只工作,不玩耍,想必聪明的小孩也会变傻,对不对? 
实际上,有些小孩就算玩了也还是有点傻。但这是另外一回事。
明确这一点后,让我们看一下可以打乱文本文件中单词顺序的脚本。正如我们说过的那样,这样的工作在实际当中可能没有一点用处,但它是有点挑战性,并且也确实需要我们使用一点令人感兴趣的脚本编写小窍门。还有,如果不是这样,您可能永远也不会知道这样的窍门何时才能派上用场。
首先,假定您有个类似于下面这样的文本文件,文件中的所有单词按字母顺序排列:
Apple
Banana
Carrot
Dog
Fish
Elephant
Giraffe
Horse
如何才能打乱这些词的顺序呢?使用像下面这样的脚本即可:

复制代码 代码如下:

Const ForReading = 1 
Const ForWriting = 2 
Set objDictionary = CreateObject("Scripting.Dictionary") 
Set objFSO = CreateObject("Scripting.FileSystemObject") 
Set objFile = objFSO.OpenTextFile("c:\scripts\words.txt", ForReading) 
i = -1 
Do Until objFile.AtEndOfStream 
    strLine = objFile.Readline 
    objDictionary.Add strLine, strLine    
    i = i + 1 
Loop 
objFile.Close 
Dim arrWords() 
Redim arrWords(i) 
intWordsLeft = i 
z = 0 
Do While intWordsLeft >= 0 
    Randomize 
    rndWord = Int((intWordsLeft - 0 + 1) * Rnd + 0) 
    intWordsLeft = intWordsLeft - 1 
    colItems = objDictionary.Items 
    strText = colItems(rndWord) 
    arrWords(z) = strText 
    z = z + 1 
    objDictionary.Remove(strText) 
Loop 
Set objFile = objFSO.OpenTextFile("c:\scripts\words.txt", ForWriting) 
For Each strItem in arrWords 
    objFile.WriteLine strItem 
Next 
objFile.Close 

哦,当然,这看起来有些不可思议;确实是件不可思议的差事(至少对系统管理员来讲是这样的)。但是,不管您相信与否,这其中是有逻辑的,我们也将逐步让您明白这种逻辑。
脚本的第一部分确实相当简单。我们定义一对常量 - ForReading 和 ForWriting,我们将在处理文本文件时使用这两个常量。然后创建两个对象:Scripting.Dictionary 和 Scripting.FileSystemObject。我们将使用 Dictionary 对象作为从文本文件中所读取单词的临时仓库;而使用 FileSystemObject 与该文本文件进行实际的交互。
接下来使用 OpenTextFile 方法打开文件 C:\Scripts\Words.txt 以进行读取。(注意常量 ForReading 的使用。)下一步,创建一个计数器变量 i 并将其值设置为 -1;我们将使用此变量跟踪文件中的单词数。为什么 i 要从 -1 而不是 0 开始?因为我们要使用 i 建立一个数组,并且由于数组中的第一项始终为 0(而不是 1),因此我们需要从 -1 开始。在我们读取第一个单词时,i 将被设置为 0,尽管听起来有些奇怪,但是大小为 0 的数组意味着该数组中包含一个数据项。
嗨,我们只是如实汇报,至于原因我们可不晓得。
接下来是下面这段代码: 

复制代码 代码如下:

Do Until objFile.AtEndOfStream 
    strLine = objFile.Readline 
    objDictionary.Add strLine, strLine    
    i = i + 1 
Loop

我们在这里所做的就是逐行读取文件。对于文件中的每一行(即每个单词),我们将该值赋给一个名为 strLine 的变量;随后使用 Add 方法将该值添加到 Dictionary 对象之中,从而将 i 值加 1。文件读取结束之后,所有的单词都存储在 Dictionary 对象之中,i 的值将为 7,这恰好是文件中的单词数减 1。(为什么?因为其中含有 8 项数据的数组的大小为 7。)
别担心;到最后您应该会明白其原因所在。
我们希望如此。
关闭文件之后,初始化数组 arrWords,设置其大小为 i (表示文本文件中的单词数减 1)。同时将 i 值赋给变量 intWordsLeft,通过它我们将知道有多少单词要被打乱顺序。最后,将变量 z 的值设为 0;我们将使用 z 将已打乱顺序的单词填充到数组中。实际上,我们要做的就是从 Dictionary 中随机取出一个单词然后将其添加到数组中。因为单词是以随机的顺序从 Dictionary 中取出的,因此它们在数组中的顺序将被“打乱”(以不同的顺序存储)。
现在,到了很有趣的这部分。建立一个 Do 循环,其一直运行到我们用完 Dictionary 对象中的所有单词。接着使用下面这两行代码从 0 和 Dictionary 对象中数据项的数目(或者至少是数据项的实际数减 1,因为 Dictionary 对象中的第一个数据项为第 0 项)之间随机选择一个数字:
Ranndomize
rndWord = Int((intWordsLeft - 0 + 1) * Rnd + 0)
之后我们将 intWordsLeft 值减 1;这样做是为了始终记住我们现在要处理的单词比之前所处理的少了一个。
那么我们需要这个随机数字做什么呢?我们现在要做的就是使用该值从 Dictionary 中随机抽取一个单词。为此,我们可以创建一个 Dictionary 项的集合,然后在变量 strText 中存储此随机选择的数据项数字的值:
colItems = objDictionary.Items
strText = colItems(rndWord)
换句话说,Banana 当前为 Dictionary 中的第 1 项。假定在生成随机数字的时候得到的是 1。这意味着我们将从 Dictionary 中将第 1 项的值取出;然后,也就意味着单词 Banana 被存储在变量 strText 中。 
明白了吗?从 Dictionary 中随机取出一个单词之后,我们即需要将该值存储到某个地方。为此我们使用数组 arrWords,使 strText 成为数组中的第一项:
Words(z) = strText
我们如何知道该值应成为第一项?因为我们将该值赋给第 z 项,而第 z 项等于 0。之后,我们立即将 z 加 1,z 将等于 1。这也意味着,通过循环下一次我们会将检索到的值赋给数组中的第二项。
单词 Banana 使用过之后,下一步就是将该单词从 Dictionary 中删除;否则我们可能会再次使用该单词。要删除此单词,只需调用 Dictionary 对象的 Remove 方法,将变量 strText 作为要删除的项进行传递即可:
objDictionary.Remove(strText)
一切均顺利完成之后,数组 arrWords 将包含一个从文本文件中所取出的已打乱顺序的单词的列表:
Banana
Elephant
Giraffe
Apple
Fish
Carrot
Horse
Dog
很好,是吧?随后我们只要打开文件 Words.txt(这次是进行写入),然后使用已打乱顺序的列表 arrWords 替换现有内容即可:

复制代码 代码如下:

Set objFile = objFSO.OpenTextFile("c:\scripts\words.txt", ForWriting) 
For Each strItem in arrWords 
    objFile.WriteLine strItem 
Next 
objFile.Close 

下次您的女儿(谁的女儿都一样)运行教育程序的时候,她所看到的将是以随机方式显示的单词。
顺便说一句,我们并没有像人们所谣传的那样对此专栏的文本进行了该脚本的测试。在您好,脚本专家!专栏中的单词可不是随机选择的;每个单词都是我们花了无数的时间进行辛勤的探索和耕耘所得到的。
事实上,就在我们做完所有认真细致的耕耘之后。我们的编辑又将所有单词的顺序随机打乱。如果您能看到该专栏编辑之前的样子,就一定会为它的美妙而吃惊不已!(编辑附注:您看到的会是这种编辑之前的情况:将您吃惊感到。使用不会但是单词这个我“美妙”。)

时间: 2024-08-07 03:26:03

编写可以打开文本文件并打乱在该文件中所找到的单词顺序的vbs脚本_vbs的相关文章

打开QQ并且让它自己输入用户名和密码的vbs脚本_vbs

可以定时打开QQ并且让它自己输入用户名和密码的脚本 复制代码 代码如下: dim program  program="c:\Program Files\Tencent\qq\QQ.exe"  '你的qq路径set Wshell=CreateObject("Wscript.Shell")  set oexec=Wshell.Exec(program)  wscript.Sleep 2000  Wshell.AppActivate "QQTang" 

c语言-我用C编写dll截取文本文件内容并返还回但是无法获得文件内容

问题描述 我用C编写dll截取文本文件内容并返还回但是无法获得文件内容 #include #define MAXLEN 16384 FILE *f; long offset=12345; long len=678; char str[MAXLEN]; void main(int *p1,int *p2,char *msg,char *str1[MAXLEN]) { //char *msg="D:WisePOM_baserawsitedata20150211001@20150211165316.t

如何把文本文件显示为网页,就像用IE打开文本文件那种效果

问题描述 如何把文本文件显示为网页,就像用IE直接打开文本文件那种效果,我想用读取数据流的方式 解决方案 解决方案二:还有啊,我的那个文件是unix格式的解决方案三:用XML+XSLT!解决方案四:直接用StreamReader读再Response.Write写不行吗?解决方案五:文本后缀名改.html解决方案六:在服务器端流读取,然后再流输出到客户端,肯定没问题的.解决方案七:在IIS中设置,让dotnet引擎处理txt文件.解决方案八:学习

android-在assets文件中打开一个图像文件

问题描述 在assets文件中打开一个图像文件 在assets文件夹中有一个.gif文件.如:assets/Files/android.gif.当打开文件的时候,会在第二行抛出异常: AssetManager mngr=getAssets(); InputStream is2=mngr.open("Files/android.gif"); 那么打开一个文本文件的代码是否适用于打开一个图像文件呢? 解决方案 打开图像文件: InputStream bitmap=null; try { b

c#-windows phone开发:如何利用编写C#将后台新添加的XAML代码永久存入XAML文件中?

问题描述 windows phone开发:如何利用编写C#将后台新添加的XAML代码永久存入XAML文件中? 具体来说就是,假如我是用动态添加控件的方式添加按钮,那再次启动软件时前次添加的按钮将会消失.其原因就是这些按钮并没有加载到XAML页面文件里.怎么样将新添的XAML代码,用C#程序保存进XAML文件中? 我是开发小白,谢谢各位了 解决方案 这个想法挺好,动态添加,建议你采用代码,直接打开xaml文件,把代码写进去,你也可以在程序中每次运行程序时都执行一下动态添加控件的代码,也一样可以实现

vc++-VC++ 6.0文本文件分行读取MFC读文件的问题

问题描述 VC++ 6.0文本文件分行读取MFC读文件的问题 VC++ 6.0文本文件分行读取,怎么样返回上一行,getline怎么才能往前读取行呢? 解决方案 vector string; ifstream inout; inout.open(文件名,ios::in); while(inout.getline(nextline, sizeof(nextline))) { temp_str = nextline; v.pushback(temp_str); } inout.close(); in

在运行->cmd中能找到javac,但进一个目录按住shft,在此处打开命令窗口却找不到javac

问题描述 在运行->cmd中能找到javac,但进一个目录按住shft,在此处打开命令窗口却找不到javac 两种情况下都能找到java命令环境变量设置为:系统变量JAVA_HOME: D:javajdk1.7.0_40Path: .......系统的.......;%JAVA_HOME%bin 解决方案 再重新设置一下环境变量试一下.在"系统变量"中,设置3项属性,JAVA_HOMEPATHCLASSPATH(不分大小写)JAVA_HOME指明JDK安装路径,就是安装时的路径D

qt txt文件 中文 乱码-Qt5中用QTextStream向txt文件中写入中文字符串,打开文件时出现乱码

问题描述 Qt5中用QTextStream向txt文件中写入中文字符串,打开文件时出现乱码 在网上查了一些关于Qt中文乱码的问题,主要是因为机器的编码问题QTextCodec::setCodecForLocale(QTextCodec::codecForName(""GBK""));QTextCodec::setCodecForCStrings(QTextCodec::codecForName(""GBK"")); QText

java类的问题-java编写从10000到99999种数字中,找到AABCC类型的所有数字

问题描述 java编写从10000到99999种数字中,找到AABCC类型的所有数字 java编写从10000到99999种数字中,找到AABCC类型的所有数字的程序.求指点 解决方案 我不认为本题有必要去"找到"这些类型的数字,我们用程序去生成的效率更高更方便. for(int i=1;i<10;i++){ for(int j=1;j<10;i++){ for(int k=1;k<10;k++){ //如果要求A,B,C不相同,加上 //if(i==j||i==k|