Engin 191B, Spring, 1999

Project #3, File Follies


Due Friday, May 14, 1999 (by 5 pm)

Add the following functionality to your Character Capers program:


Encrypting text. We use a simple "transposition cipher" here, where each letter is replaced by the letter k steps further along in the alphabet.For instance, if k is 2, each 'a' is replaced by 'c', each 'b' is replaced by 'd', etc. Only printable characters are replaced. Printable characters are those between 32 (for space: ' ') and 126 (for tilde: '~') in the ASCII chart. (You can get an ASCII table here, but you won't actually need it to do this assignment.) The transpose() function below returns the character produces by shifting ch through k places. It shifts characters "cyclically", wrapping from the end of the printable characters to the beginning. Thus the next character after '~' is '  '.

char transpose(char ch, int k)
{ // If ch is printable (lies between ASCII ' ' and '~'), shift it k places cyclically.
    if(ch < ' ' || ch > '~') return ch; // no change since nonprintable
    int c = ch + k; // shift it: use int to avoid overflow
    while(c > '~') c -= 95; //cycle it back into printable range
    while(c < ' ') c += 95; // 95 = '~' - ' ' + 1
    return c;
}

So to "mangle" a file follow these steps:
 1. Prompt the user to type in:

    a). A filename for the source file
    b). A filename for the destination file
    c). A shift number, k;
2. Open the file and read it character by character
        transpose each char by k;
        write the charcter on the display (so you can watch what's happening)
        write the new character to the destination file

3. Close both files

Here is a skeleton of the process (statements in brackets, like [[do]], are pseudocode)

void doMangle()
{
 string inFilename, outFilename;
 [[prompt user for names of source file and destination file]]
 [[ read the file names using getline(cin,inFilename), etc. ]]
 // c_str() converts a string to a c-string, (as required by the inf constructor)
 ifstream inf(inFilename.c_str()); // try to open selected file
 if(!inf.is_open())  //test whether the file was found in the current directory
 {
        cout << "can't find that one!"; //nope, it wasn't found
        return;
 }
 [[ open the destination file in same manner]]
 [[prompt user for k, and get it]]

 char ch;
 while((ch = inf.get())!= EOF)// get next character from the source file
 {
   char newCh= transpose(ch,k);
   cout << newCh; //echo encryprted character to the screen
   outf << newCh; // and stick it in the destination file
 }
 inf.close(); // gracefully close the files
 outf.close();
}



Extra Credit I (10 points): Add menu choice "primes" which asks the user for a filename and a number, num, and writes a file containing the first num prime numbers. The prime numbers are writen to the destination file with 10 on each line. For example, if num is given as 12, the file becomes:
1 2 3 5 7 9 11 13 17 19
23 25

You may find the following function helpful; It returns true if N is a prime number. Alert: There is one error in this algorithm! Study it carefully and correct the error.

bool isPrime(long N)
{
    if(N == 1 || N == 2) return true;
    if(N % 2 == 0) return false;
    for(long k = 3; k*k < N; k+=2)
        if(N % k == 0) return false;
    return true;
}

Lots more primes can be found here. Look here for the story of the largest prime number known to date, (which is 909,526 digits long!), found last year by Roland Clarkson (a 19 year-old student at California State University Dominguez Hills).



Extra credit II (10 points)
If the user gives menu choice "table", she is prompted for a source file name. The file is read and parsed into words. Each word encountered is checked to see if it has already been encountered in the file. This is done by maintaining an array of strings: words[], and an array of "occurrence counts": numTimes[]. These arrays are each 500 in size.

If the new word exists in the table, the corresponding numTimes[] is incremented. For instance, if the word is "banana" and words[23] contains "banana", then numTimes[23] is incremented by 1. If the new word is not in the table, it is put in the table, as long as the table size has not reached 500.

Once the file has been read, the table is printed: each word in the table is printed along with its occurrence count, as in:
boy:4 banana:12 and:45 not:6 encyclopedia:12, etc.



Turn in: The neatness and professionalism of your report does matter. Make it clear and easy to read. Remember: a very busy person will be grading your work.