
VBScript solution to Event 9 in the 2008 Winter Scripting Games.
Solutions are also available for Windows PowerShell and Perl.
If there’s a theme throughout the Scripting Games it’s this: the Scripting Guys are fairly good at writing scripts, but absolutely abysmal at testing and debugging scripts. Event 9 serves as a good example of that. As you’re about to see, there’s not much to this script; we were able to solve the problem using less than 15 lines of code. To pick up on a recurring theme, however, we didn’t realize that we had solved the problem.
Why not? Well, in our script we read in the original text file and store the value in a variable named strContents. We then reverse all the words in that file, storing these reversed words in a variable named strNewContent. We then conclude the script by echoing back the value of strNewContent.
Or at least that’s what we were supposed to do. Instead, we echoed back the value of strContents, the original file. How many times did we run this script before we realized our mistake? Let’s put it this way: don’t ask.
On the bright side, however, once we changed the last line of the script to read Wscript.Echo strNewContent, well, at that point everything worked perfectly.
Here’s the code:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Alice.txt")
strContents = objFile.ReadAll
objFile.Close
arrWords = Split(strContents, " ")
For i = 0 to UBound(arrWords)
arrWords(i) = StrReverse(arrWords(i))
Next
strNewContent = Join(arrWords)
Wscript.Echo strNewContent
So how does this script perform its magic? Well, there’s nothing very magical about the way it starts off; we simply define a constant named ForReading and set the value to 1. From there we create an instance of the Scripting.FileSystemObject object, then use the OpenTextFile method to open the file C:\Scripts\Alice.txt for reading:
Set objFile = objFSO.OpenTextFile("C:\Scripts\Alice.txt")
As soon as the file is open we use the ReadAll method to read in the entire contents, storing those contents in a variable named strContents. And then, because we no longer need the file, we call the Close method and close Alice.txt.
What does that mean? That simply means that strContents is now equal to this:
'Curiouser and curiouser!' cried Alice (she was so much surprised, that for the moment she quite forgot how to speak good English); 'now I'm opening out like the largest telescope that ever was! Good-bye, feet!' (for when she looked down at her feet, they seemed to be almost out of sight, they were getting so far off). 'Oh, my poor little feet, I wonder who will put on your shoes and stockings for you now, dears? I'm sure _I_ shan't be able! I shall be a great deal too far off to trouble myself about you: you must manage the best way you can; --but I must be kind to them,' thought Alice, 'or perhaps they won't walk the way I want to go! Let me see: I'll give them a new pair of boots every Christmas.'
Note. OK, technically strContents is one big long line, without any line breaks. That doesn’t make for a very nice-looking Web page, however, so we inserted some line breaks simply to make things readable. We’ll do the same thing when we show you our modified output. |
Now comes the tricky part. If you got this part right then we’re willing to bet just about anything that you were able to solve the problem. (Well, like we said “just about” anything.) If you didn’t get this part right, well, maybe you solved the problem and maybe you didn’t. For the Scripting Guys, though, the easiest way for us to tackle this event was to begin by executing this line of code:
arrWords = Split(strContents, " ")
What we’re doing here is using the Split function to create a giant array consisting of all the words in the variable strContents. (We know we’ll end up with all the words, because we’re splitting on each blank space.) When the Split function finishes doing its thing, the first few items in arrWords should be these:
'Curiouser and curiouser!' cried Alice
From here on our task gets much easier. To reverse each individual word in the file all we have to do now is set up a For Next loop that starts at 0 and loops through the last item in the array (the upper bound, or UBound, item):
For i = 0 to UBound(arrWords)
Note. Why do we start at 0? You already know the answer: because the first item in an array is always given the index number 0. |
Inside that loop we do nothing more than execute this line of code:
arrWords(i) = StrReverse(arrWords(i))
What are we doing here? Well, we’re simply taking the first item in the array (arrWords(i)) and using the StrReverse function to reverse all the letters in that item. In other words, if item 0 happens to be ‘Curiouser (which it is), then this line of code reverses the characters in ‘Curiouser and assigns this modified value to item 0. That means that the first word in the array is now this:
resuoiruC'
Which, of course, is just exactly what we wanted the first item to be. After reversing the characters in the first item we go back to the top of the loop and repeat this process with this next item in the array. In no time at all the first five items in the array will look like this:
resuoiruC' dna '!resuoiruc deirc ecilA
All that’s left now is to take this list of words and recombine them into a single line of text. Remember when we used the Split function to split the original text of Alice.txt into an array? Well, now we use the Join function to reverse that process, recombining all the words into a single line, and storing this new line of text in a variable named strNewContent:
strNewContent = Join(arrWords)
Note. By default, the Join function separates the recombined items using blank spaces. Alternatively, we could have used code like this to separate words using commas: strNewContent = Join(arrWords, ",") But then we wouldn’t have gotten credit for this event. |
At that point it’s time to echo our modified value back to the screen:
resuoiruC' dna '!resuoiruc deirc ecilA ehs( saw os hcum ,desirprus that rof eht tnemom ehs etiuq togrof woh ot kaeps doog ;)hsilgnE won' m'I gninepo tuo ekil eh t tsegral epocselet taht reve !saw ,eyb-dooG '!teef rof( nehw ehs dekool nwod ta reh ,teef yeht demees ot eb tsomla tuo fo ,thgis yeht erew gnitteg os raf .)ffo ,hO' ym roop elttil ,teef I rednow ohw lliw tup no ruoy seohs dna sgnikcots rof uoy ,won ?sraed m'I erus _I_ t'nahs eb !elba I llahs eb a taerg laed oot raf ffo ot elbuort flesym tuoba :uoy uoy tsum eganam eht tseb yaw uoy ;nac tub-- I tsum eb dnik ot ',meht thguoht ,ecilA ro' spahrep yeht t'now klaw eht yaw I tnaw ot !og teL em :ees ll'I evig meht a wen riap fo stoob yreve '.samtsirhC
It’s a thing of beauty, isn’t it?