COMP 142: Project 3 --- Mesostics

A mesostic is a poem arranged in such a way that a word appears vertically consisting of single letters from the horizontal lines of the poem. Here's an example, albeit with a misspelling. For this project, you will create a program that arranges the words of a poem into a mesostic by adjusting the spacing of the lines of the poem.

Your program will work by opening and reading the lines of a text file. The first line of the file will contain a single word without spaces. The subsequent lines will contain the lines of a poem; these lines may include spaces. Your program will print out the lines of the poem spaced so that the single word from the beginning of the file can be read vertically in the output.

It is guaranteed that all the files I use to test your program will consist of poems for which mesostics can be found. You should also note that this concept only works in computational form because typical computer programs produce their output in a monospace (a font where each letter, number, or punctuation symbol takes up the same amount of horizontal space), as opposed to a proportional font (a font where the amount of horizontal space used for a character is proportional to the normal amount of horizonal space the character actually would take up).

Examples: This is a monospace font. This is a proportional font.

Program details and algorithms

You should use a struct in your program to hold the mesostic. The declaration of the struct should be the following:
struct mesostic
{
  string vert_word;
  vector<string> poem_lines;
  vector<int> match_positions;
};
The struct contains the following information about a mesostic: Let us illustrate these pieces with a short example. Say your input file contains the four lines:
cat
this cuddly
animal
bites me
When your program reads this file, it would create a mesostic struct with vert_word as "cat" and poem_lines consisting of the strings "this cuddly", "animal", and "bites me" in a vector. match_positions would contain a vector of 5, 0, and 2, because the 5th position (counting from zero) in the string "this cuddly" is 'c', the 0th position in "animal" is 'a', and the 2nd position in "bites me" is 't'. Naturally, you will need to write code to calculate the integer values in the match_positions vector.

It is also worth pointing out that poem_lines contains three strings and match_positions contains three integers.

After your program calculates this information, it should be able to print the poem (using cout and some blank spaces) as:

this cuddly
     animal
   bites me
Notice how the word "cat" is found vertically in the output.

How the program should work

The user should be asked to type in the name of a text file that contains a mesostic. The user will not type in the vertical word and the lines of the poem manually; that information will be read from the text file. Your program should then (1) create a struct to hold the mesostic, (2) read in the lines of the text file into the vert_word and poem_lines vector, (3) calculate and set the appropriate values of the match_lines vector, and (4) display the mesostic arranged so the vertical word can be seen in the lines of the poem. Obviously, some of the lines of the poem will need to be moved to the right on the screen; this can be done by printing a specific number of blank spaces before each line of the poem. The mesostic should always be left-justified; that is, there should be at least one line of the poem that is printed without any leading spaces. This line is not necessarily the first line of the poem.

Parts of the program

You should use functions to break up parts of your program. At a minimum, you should have a function that reads in the file, a function that calculates the match_positions vector, and a function that prints the mesostic. You may use other functions as you see fit.

Here are some suggested prototypes:

Reading the file

Reading the file is a bit tricky because we need to use getline (because each line of the poem may have spaces). What I suggest doing is using one initial call to getline to read in the vertical word of the mesostic (save this into vert_word), and then use a loop to read in the lines of the poem. Using a loop with getline is a little different than what we're used to; we don't use the eof() function. Instead, use this idea:
mesostic meso;
string s;

getline(infile, meso.vert_word); // read the vertical word directly
while (getline(infile, s))
{
    meso.poem_lines.push_back(s);
}
Things will get wonky if you try to use while (!infile.eof()) here.

Calculating match_positions

You must devise an algorithm for this. Use the example above to figure out how the algorithm should work and what numbers should go into the match_positions vector. You will need a loop. You can loop over either the letters (chars) of the vertical word, or the entire lines (strings) of the poem. It doesn't matter either way, since it's guaranteed there are the same number of chars in the vertical word as there are lines in the poem.

Printing the mesostic with the correct spacing

Again, you will need to devise an algorithm for this, and this one will take a little bit of thought. Here's a hint: the number of spaces to add to each line of the poem is dependent upon more than just that individual line --- the number depends on a factor that can only be deduced by examining the entire poem.

Work out some examples (e.g., from the text files) on graph paper to figure out this algorithm. The graph paper is useful because you can put one character in each square on the paper and easily see how things are supposed to line up. See if you can figure out what the connection is between match_positions and how many leading spaces are added to each line of the poem.

Coding style

All the normal guidelines for coding from previous projects apply. Do not use any global variables.

Testing your program

You should test your program thoroughly to make sure it works correctly. Here are some sample mesostic files to try: meso0.txt meso1.txt meso2.txt meso3.txt meso4.txt

Sample input and output

The program's output is in normal text; what the user types is in bold. Each test of the program is shown separately; the SAMPLE RUN parts are not part of the output.
-----------------------------------------------------
SAMPLE RUN 1
-----------------------------------------------------
Mesostic input file: meso0.txt

this cuddly
     animal
   bites me
   
-----------------------------------------------------
SAMPLE RUN 2
-----------------------------------------------------
Mesostic input file: meso1.txt

  let us make
      of this
      modest
        place
    a room holding
tons of love
       (&, naturally, much good food, too)
       
-----------------------------------------------------
SAMPLE RUN 3
-----------------------------------------------------
Mesostic input file: meso2.txt

    life is a
   companion
  treat it with
     generosity
    sincerity
patience and
  love
  
-----------------------------------------------------
SAMPLE RUN 4
-----------------------------------------------------
Mesostic input file: meso3.txt

     music
  indeterminacy
 words
    collaboration
     speech
invention
    silence
     cage
     
-----------------------------------------------------
SAMPLE RUN 5
-----------------------------------------------------
Mesostic input file: meso4.txt

    it's just
great theater. there's
       an ordinary guy, balding,
     unknown,
      leaves sunny stratford
penniless, a few plays
   and poems in a bag, ends up on
     the globe stage a master,
  unrivalled
     bard, 100%
    literary genius.

Hints

What to turn in

Through Moodle, turn in your code as a file called main.cpp or mesostic.cpp. Please do not upload anything other than the .cpp file.

Challenge Problem

Print the mesostic using uppercase letters for the vertical word to make it easier to find quickly. For example, the output for meso4.txt would change to
    it'S just
great tHeater. there's
       An ordinary guy, balding,
     unKnown,
      lEaves sunny stratford
pennileSs, a few plays
   and Poems in a bag, ends up on
     thE globe stage a master,
  unrivAlled
     baRd, 100%
    litErary genius.
For historical reasons, the toupper function returns an int, not a char. If you use toupper to convert from lowercase to uppercase, you will need to cast the return value of toupper to a char to get it to print correctly.