Magenta's Mini-C++ Tutorial

Lesson 1: Making code more compact

Rather than use a lot of if-then expressions for selecting a letter, do this:

char consonant() {
        static string consonants("BCDFGHJKLMNPQRSTVWXYZ");
        return consonants[rand()%consonants.length()];
}

char vowel() {
        static string vowels("AEIOU");
        return vowels[rand()%vowels.length()];
}

char letter() {
        return 'A' + rand()%26;
}
and then call consonant(), vowel(), or letter().

Lesson 2: The auxiliary things you didn't notice from lesson 1

There's still some improvements to be made... rather than doing "int ha = 1; while (ha==1) ...", just do "for (;;) ...", which is the blessed-by-the-gods way of doing an infinite loop. Sane compilers won't generate a warning on that, because it's the accepted style.

You also seem to be missing a fair amount of code (it abruptly ends), and you forgot to turn your [s into [s so that they don't try to hardlink your array sizes.

Using a string (as I did above) instead of a char[] is considered much cleaner and safer, though in this case it doesn't really matter.

There's no reason to declare an array of "letters," since the nth letter is just 'a'+n. That is, 'a'+3 == 'd'. This is standardized on all ASCII-speaking machines, as well as most other character sets. Remember, in C/C++, a character constant is an int, it's just formatted in a human-readable way. You're also thinking like a human, rather than a programmer, by counting from 1 instead of 0.

The loops for doing a random number of things can be made much more simple as well. Rather than saying:

int lets=rand()%7;
for (int i = 0; i < lets; i++)
do this:

for (int i = rand()%7; i > 0; i--)
They're equivalent, assuming you're not using the loop index variable within the loop. If you do strictly need to count upwards, though, and aren't just repeating a loop a specific number of times, you still have to use a temporary variable though.

That way of doing extensions is fugly, though it works well enough. I'd personally do something like this:

const int NUM_EXTENSIONS = 6;
const char *EXTENSIONS[NUM_EXTENSIONS] = {"dat"
                                         ,"bat"
                                         ,"exe"
                                         ,"sys"
                                         ,"vxd"
                                         ,"drv"
                                         }
or the like. And the reason I format my array in that weird-looking way is twofold - it's much more readable, and it's the way that XEmacs' code-indentation stuff likes it to be done.

As far as array lengths and such, you really shouldn't hard-code those numerically. If you really don't care about changing the contents of the arrays dynamically (that's why I always use string for that stuff), then at least do something like this:

const char *vowels="aeiou";
const int numvowels=strlen(vowels);

...

char myvowel = vowels[rand()%numvowels];

That way, if you decide to add in, say, y or w (FWIW, w is sometimes - but very rarely - considered a vowel, such as in the word cwm), you just add it into the string and everything keeps on working. And if you later decide to take them out, you don't have to worry about segfaults/GPFs or other weird behavior (such as getting garbage characters).

I don't deny that I used to code pretty sloppy, myself. Learning proper coding style or methodology isn't something which happens overnight, but I hope that I am, at the very least, being helpful in showing you The Right Way of doing these things. :)