What's wrong with this code?

Pages: 12
Hi, everyone. I'm working on a program that allows the user to play a game called a Mad Lib. I'm doing it in a couple parts. Right now, my code is supposed to read the Mad Lib file and ask the user for information to fill in parts of the story. For some reason, my code isn't outputting the questions it's supposed to ask, and I'm not sure why. I worked with a tutor from my school earlier today, and we fixed some things, but she had another appointment, so she couldn't help me keep working on it. Here's a comparison of what I'm getting, and what I should be getting, when I run my code through the tests it needs to pass:
Starting Test 1

This first test is trivial, reading the following file:
My pet cat is very <{> <adjective> . <}> <#> So is my dog . <#>
There is one prompt: "adjective" which needs to turn to "\tAdjective: "

> Please enter the filename of the Mad Lib: /home/cs124/projects/madLibTrivial.txt
> \t:
Exp: \tAdjective:
happy
>
Exp: Thank you for playing.\n

Test 1 failed.
------------------------------------------------------------

------------------------------------------------------------
Starting Test 2

This second test has 13 prompts. The file is:
I feel like yelling <{> <web_site_name> <}> every time I <verb> the <#>
Internet . So many <plural_noun> to look for , so many <plural_noun>
to find . <#> <#> My mother asked me , <{> <proper_noun> , what is so
<adjective> about <#> the Web ? <}> <{> Well , <}> I said , <{> just
the other day I did a search for <noun> <#> by entering <[> <noun>
<boolean_operator> <noun> <]> in a search <#> engine . And it returned
<favorite_website> and <another_website> . It's <#> just so <adjective>
! <}> <#> <#> And then she knew what I meant . I felt so happy ! <#>

> Please enter the filename of the Mad Lib: /home/cs124/projects/madLibWeb.txt
> \t:
Exp: Web site name:
Automobile Magazine.com
> \t: \t:
Exp: Verb:
drive
> \t:
Exp: Plural noun:
cars
> \t:
Exp: Plural noun:
motorcycles
> \t:
Exp: Proper noun:
New York
> \t: \t:
Exp: Adjective:
red
> \t:
Exp: Noun:
Porsche
> \t:
Exp: Noun:
BMW
> \t:
Exp: Boolean operator:
xor
> \t:
Exp: Noun:
Ferrari
> \t:
Exp: Favorite website:
Car and Driver
>
Exp: Another website:
Ferrari.it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/***********************************************************************
* Program:
*    Project 09, Mad Lib Program
*    Sister Unsicker, CS124
* Author:
*    Lanie Molinar
* Summary: 
*    This program is the second part of the Mad Lib project. It reads the Mad 
*    Lib from a file, making sure it's the right size, and prompts the user 
*    for words or phrases to fill in the needed text.
*
*    Estimated:  6.0 hrs   
*    Actual:     0.0 hrs
*      Please describe briefly what was the most difficult part.
************************************************************************/

#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

void getFilename(char fileName[])
{
   cout << "Please enter the filename of the Mad Lib: ";
   cin >> fileName;
}

void askQuestions(char story[])
{
   if (story[0] != '<' || !isalpha(story[1]))
      return;
   cout << "\t";
   story[1] = toupper(story[1]);
   for (int iStory = 2; story[iStory] == '>'; iStory++)
   {
      if (story[iStory] == '_')
         cout << " ";
      else
         story[iStory] = tolower(story[iStory]);
   }
   cout << ": ";
   cin >> story;
}

int readFile(char story[][33], char fileName[])
{
   ifstream fin(fileName);
   if (fin.fail())
   {
      cout << "Error reading file " << fileName << ".\n";
      return 0;
   }
   int numWords = 0;
   while (fin >> story[numWords])
   {
      askQuestions(story[numWords]);
      numWords++;
   }
   if (numWords > 256)
   {
      cout << "Error reading file " << fileName 
         << ". It has more than 256 words.";
      return 0;
   }
   fin.close();
   return numWords;
}

/**********************************************************************
*    The main function tells a program where to start.
***********************************************************************/
int main()
{
   char story[256][33];
   char fileName[256];
   getFilename(fileName);
   int wordCount = readFile(story, fileName);
   return 0;
}
Your draft promises a lot of fiddling with pointers. Is it allowed to you using std::string, std::stringstream, and std::vector? That would simplify your task a lot.
I don't think so. I've never even heard of any of those. I don't know if this helps you understand what I can and can't use, and what I've learned about, but this course is all about procedural programming with C++. I don't learn about object-oriented programming until next semester.
All of the above mentioned tools can be also used in procedural programming manner, but these are basic in C++. The reason of this: It's bad style using fixed arrays and pointers for string manipulations. Because that's extremely error prone.

To become a flavour of what I mean: Merely printing the matching grammar word to console it needs complicated code like this. Yes, that's very complicated (and therefore quite likely wrong).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void askQuestions(char story[])
{
   char wordType[33];  // holds the Grammar_word
   char *storyPtr = story+5; // points to the 6th memory address
                             // within story[]
   char * wordstartPtr = story;
                      
   while(*ptr != '\0')
   {
       wordPtr = wordType;  // points to wordType[0]
       
       // detecting a question
       if (
              *(storyPtr-5) == '<'
           && *(storyPtr-4) == '{'
           && *(storyPtr-3) == '>'
           && *(storyPtr-2) == ' '
           && *(storyPtr-1) == '<'
       ){
           *storyPtr = toupper(*storyPtr)
           while (*storyPtr != '>')
           {
               *wordPtr = storyPtr;
               if (*wordPtr == '_') *wordPtr = ' ';
               
               ++wordPtr, ++storyPtr;
           }
           *wordPtr = '\0';
       }  
       cout << wordType << '\n';
       // ...
    }
}          
Hmm. I'll have to try this. I've learned about pointers, but I didn't think to use them since I was following pseudocode given by my instructor. This is what she gave us in the design document:
askQuestions(text) 

   IF text[0] ≠ < or !isalpha(text[1]) 

       return 

   PUT tab and toupper(text[1]) 

   FOR iText = 2 until text[iText] = > 

        IF text[iText] = _ 

             PUT space 

        ELSE 

             PUT tolower(text[iText]) 

    PUT colon and space 

    GET text 

END


readFile(story) 

   getFilename(fileName) 

   OPEN fin from fileName 

   IF error in fin 

      DISPLAY error 

      RETURN 0 

   WHILE numWords < 256 and READ story[numWords] from fin 

      askQuestions(story[numWords]) 

      numWords++ 

   CLOSE fin 

   RETURN numWords 

END
If you want a good beginners book for learning real good coding style with C++ , I recommend 'Programming: Principles and Practice Using C++ 2nd Edition' from Bjarne Stroustrup, the inventor of C++
Thanks. Do you have any suggestions for now, though? I've got to get this project submitted with the tools I already have.
Are you sure you have copied *exactly* your teacher’s pseudocode?
Does “GET text” really be at the end of “askQuestions(text)” ? Should we suppose that function should loop the entire file or be recursive?
Are you sure your indentation and upper/lower letters are correct?

Did your instructor give you any more advice/directions?

And, sorry, is this a school / university assignment?
What do you want, final code or advice?

I’m sorry about all these questions, but the more specific you can be the better we can help you.
This is the exact pseudocode my professor gave. Yes. This is an assignment. I would like advice to help me understand what I could be doing wrong and correct it. I'm sure my indentations and casing are correct. Here's more information about the assignment and some other information she posted in an announcement about it:

Assignment description:
The second part of the Mad Lib project (the first part being the design document due earlier) is to write the code necessary read the Mad Lib from a file and prompt the user:
Please enter the filename of the Mad Lib: madlibZoo.txt
Plural noun: boys
Plural noun: girls
Type of liquid: lemonade
Adjective: fuzzy
Funny noise: squeak
Another funny noise: snort
Adjective: hungry
Animal: mouse
Another animal: blue-fin tuna
Note that there is a tab before each of the questions (ex: "Plural noun:")
Hints
Your program will not need to be able to handle files of unlimited length. The file should have the following properties (though you will need to do error-checking to make sure):
• There are no more than 1024 characters total in the input file.
• There are no more than 32 lines in the input file.
• Each line in the input file has no more than 80 characters in it.
• There are no more than 256 words in the input file including prompts.
• Each word in the input file is no more than 32 characters in length.
Hint: To see how to declare and pass an array of strings, please see Chapter 3.0 of the text.
Assignment
Perhaps the easiest way to do this is in a four-step process:
1. Create the framework for the program using stub functions based on the structure chart from your design document.
2. Write each function. Test them individually before "hooking them up" to the rest of the program. You are not allowed to use the String Class for this problem; only c-strings!
3. Verify your solution with testBed:
testBed cs124/project09 project09.cpp
4. Submit it with "Project 09, Mad Lib" in the program header.

Announcement:
Remember that the string class is not allowed on this project. That is, all text must be stored in c-strings or arrays of characters. For example, you would be docked if you used the first example on the project: 
string text = "This variable is not allowed on the madlib project."; 
char text[256] = "This is how you should store text in the madlib project."; 
Here are some hints for the project: 
• As always, use the rubric as your guide. 
• You can find a working example of the project at /home/cs124/projects/proj10.out. There are five example files found in that same directory called madLib*.txt. Use this example to help you determine the output and interaction of your program. Here is a screencast of how to run the proj10.out file: http://www.screencast.com/t/KH0ALYeDM2az  
• "Example 3.0 -Array of Strings" gives a great example of how to declare, fill, and display an array of strings. Many students find referring to this example helpful when working on the project. 
• To have functional cohesion in your program, a function should do one thing, and one thing only. This doesn't mean it should be one line, but rather, it should be accomplishing one conceptual piece of work. 
Error Checking
On page 298 of the textbook it describes the file format and states that you will need to do error checking to make sure the file conforms to this format. Only requirements that affect data storage need to be verified. Here is the list and the important errors to check for: 
• There are no more than 1024 characters total in the file. (Do not need to verify) 
• There are no more than 32 lines in the file. (Do not need to verify) 
• Each line has no more than 80 characters in it. (Do not need to verify) 
• There are no more than 256 words in the file. (Needs to be verified) 
• Each word is no more than 32 characters in length. (Needs to be verified) 
Helpful functions
Some functions that you may find useful for the project are strlen(), isalpha(), ispunct(), tolower(), and toupper(). To use these you will need to include <cctype> and <cstring>.  
Last edited on
That are good hints :)
Here some suggestion how to taccle your assignment:

1. Make a flow chart. (I hope you have made this still, have you?) Don't take this easy. It's the part for which you should spend most of the time. Your chart is ready first then, when you will be able comprehending all all steps with your head. I recommend that you first make a rough one, and then refining this chart iterative.
There it could be, that it runs to a blind lane. If you have such feel, don't hesitate making a new approach. And be aware that you can split the whole stuff to many separate functions: Each of this functions should be as small as possible. And it's good style assembling your functions with help of lower level functions.

2. As I mentioned above, now you have mastered the hardest part. All you need to do is moulding your chart into code. Try to test each of your functions separately, resist of coding all functions in a rush and then wondering that the whole stuff will not work - if you can't resist this, you can be sure that your debugging time will be much longer then if you had tested each function separately.

If you want, you can post a link to your flow chart (if you're able load it up somehow).
Good luck!
Unfortunately, I'm blind, so the flow chart isn't something I can do. I was given an English description of a structure chart to work with, but it only includes those functions I have in my code. The student who's tutoring me says I should be able to make it work with those functions, but she had to stop helping me when she had another appointment.
Oh, sorry to hear. Maybe you are been able to assemble a chart in your mind (with help of some notes to your braille board, have you such thing?)

I'm fascinated of how the blind guys are be able to code. Maybe it would be feasible if you use a ballpen and draw to a paper which lays on a soft suface so you could trace the lines with your fingers?
Hi. I'm used to my blindness. I've been completely blind or had very little sight all my life, so it's no problem. I'm not sure what you mean by a Braille board, but I'm pretty sure I don't have one. I'm also not a very visual or spatial thinker, so I'm not too sure drawing a chart in any form would help much. I just want to figure out how to get this to work. I would think it would be possible with what functions I have, as the design document with the structure chart and pseudocode only contains these. Should I look into using using pointers in some areas or something? I know the tutor I've been working with doesn't have time to work with me, so I'm thinking about seeing if another is available.
I'm working at time at a code solution for your void addQuestions( char word[]); function. As far as I consider this function now, it takes merely a single word (and not an array of words, which would be a two-dimensional array). Be patient, will post a solution which will be good commented. But my English is very poor, so the commenting will take most of the time.

And I'm a type who always think visual or spational. All the world consists of objects, and so I assemble my mind stuff in my head to objects, even music :) This may be the reason for having difficulties with instructiveness texts, also my memory performance is terribble together with my concentration ability :)

btw: How do you recognize your reading text?
Your code with some comments.
You’re close to finish the first part.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// • There are no more than 256 words in the file. (Needs to be verified) 
// • Each word is no more than 32 characters in length. (Needs to be verified) 
// Where do you verify the latter?

// You're not following the pseudocode. You're not obliged, of course, but if
// you're stuck, perhaps that should be the first attempt.
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

void getFilename(char fileName[])
{
   cout << "Please enter the filename of the Mad Lib: ";
   cin >> fileName;
}

// askQuestions(text)
//     IF text[0] ? < or !isalpha(text[1])
//         return
//     PUT tab and toupper(text[1])
//     FOR iText = 2 until text[iText] = >
//         IF text[iText] = _
//             PUT space
//         ELSE
//             PUT tolower(text[iText])
//     PUT colon and space
//     GET text
// END
void askQuestions(char story[])
{
    // Suggestion: add a line of code like
    // std::cout << "story: " << story << '\n';
    // here and watch what your program does.
   if (story[0] != '<' || !isalpha(story[1]))
      return;
   cout << "\t";
   // Just follow what your professor says: PUT means output, i.e. 'cout'.
   // You don't need to modify "story" here: you need to display the alternative.
   // If in "story" there's a '_', you need to 'cout' a space.
   // Otherwise, you need to display the lower version of the character
   // in "story". Remainder: std::tolower returns an int: you need to cast it
   // back into 'char' when you 'cout' it.
   story[1] = toupper(story[1]);
   for (int iStory = 2; story[iStory] == '>'; iStory++)
   {
      if (story[iStory] == '_')
         cout << " ";
      else
         story[iStory] = tolower(story[iStory]);
   }
   cout << ": ";
   cin >> story;
}

// readFile(story) 
//    getFilename(fileName) 
//    OPEN fin from fileName 
//    IF error in fin 
//       DISPLAY error 
//       RETURN 0 
//    WHILE numWords < 256 and READ story[numWords] from fin 
//       askQuestions(story[numWords]) 
//       numWords++ 
//    CLOSE fin 
//    RETURN numWords 
// END 
int readFile(char story[][33], char fileName[])
{
   ifstream fin(fileName);
   if (fin.fail()) // if(!fin)
   {
      cout << "Error reading file " << fileName << ".\n";
      return 0;
   }
   int numWords = 0;
   // You could overflow!
   // • There are no more than 256 words in the file. (Needs to be verified)
   // You need to stop at 256 words, since you don't have more room (anyway
   // the file you posted has got 88 words, so it won't break your program).
   while (fin >> story[numWords])
   {
      askQuestions(story[numWords]);
      numWords++;
   }
   if (numWords > 256)
   {
      cout << "Error reading file " << fileName 
         << ". It has more than 256 words.";
      return 0;
   }
   fin.close();
   return numWords;
}

/**********************************************************************
*    The main function tells a program where to start.
***********************************************************************/
int main()
{
   char story[256][33];
   char fileName[256];
   getFilename(fileName);
   int wordCount = readFile(story, fileName);
   // Now display what's there into story ;-) 
   // This is the most important check.
   return 0;
}

I have an application called a screen reader on my computer that reads what's on my screen.
I originally tried following the pseudocode, but my tutor had me change it. I'll try to work with this. I wasn't taught much about the toupper and tolower functions before I used them, and the few examples I read showed it being used in the way I wrote it. What does tolower return. I thought it returned the letter with the changed case. I didn't post a file that would be read by the program. All I posted was the code, test results, and information about the assignment. Also, I thought the if statement I have in the for loop in askQuestions would change a _ to a space. I'm not supposed to display the story just yet. That's next week's work.
Also, I keep seeing people writing things like "std::cout". What is this? I've seen cout by itself, but never with the std in front of it.
Because toupper() and tolower():
In standard C and C++ all characters are represented as numbers. So e.g. 'A' has number 65, and 'a' has number 97. It's just the manner how letters will be memorized by the computer. Each of this number is assigned to a picture of the real letter. The code at which these numbers will be assigned to its pictures is called ASCII (American Standard Code for Information Interchange).
'toupper()' and 'tolower()' just exchange these code numbers in such manner, that tolower() is returning the code for an upper case code to its fitting lower case code and toupper() is returning always the upper number code of a number. Other numbers they are just return unchanged. Consider that they both returning an int-type (instead of a char), and they can take an int as input argument.

The std:: is just a namespace for a set of facilities provided by the standard C++. All functions, classes, and constants provided by the standard belongs to namespace std::. A namespace belongs to their full name, so e.g. std::cout, std::cin, std::fstream and so far. All functions provided by the standard must preceded by this namespace. But you can tell the compiler that all facilities of a namespace should mapped to the local namespace. That are all tools without a namespace. This will be made for std:: via using namespace std;. But it's a good style not mapping namespaces together, just because with preceding namespaces it's visible to what namespace an utility belongs. I for example use almost all the preceding namespaces in my code. But for small code pieces it's sometimes annoying.
Last edited on
I worked with another tutor and made more modifications to my code. He didn't think anything was wrong with the toupper and tolower functions, or that I needed to cast them, but had me change a few other things. He says I'm close to getting it working. Can you please take another look?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/***********************************************************************
* Program:
*    Project 09, Mad Lib Program
*    Sister Unsicker, CS124
* Author:
*    Lanie Molinar
* Summary: 
*    This program is the second part of the Mad Lib project. It reads the Mad 
*    Lib from a file, making sure it's the right size, and prompts the user 
*    for words or phrases to fill in the needed text.
*
*    Estimated:  6.0 hrs   
*    Actual:     0.0 hrs
*      Please describe briefly what was the most difficult part.
************************************************************************/

#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

void getFilename(char fileName[])
{
   cout << "Please enter the filename of the Mad Lib: ";
   cin >> fileName;
}

void askQuestions(char story[])
{
   if (story[0] != '<' || !isalpha(story[1]))
      return;
   else if (story[0] == '<' && isalpha(story[1]))
   {
      cout << "\t";
      story[1] = toupper(story[1]);
      cout << story[1];
      for (int iStory = 1; story[][iStory] == '>'; iStory++)
      {
         if (story[][iStory] == '_')
            cout << " ";
         else
         {
            story[iStory] = tolower(story[iStory]);
            cout << story[][iStory];
         }
      }
      cout << ": ";
      cin >> story;
   }
}

int readFile(char story[][33], char fileName[])
{
   ifstream fin(fileName);
   if (fin.fail())
   {
      cout << "Error reading file " << fileName << ".\n";
      return 0;
   }
   int numWords = 0;
   while (fin >> story[numWords])
   {
      askQuestions(story[numWords]);
      numWords++;
   }
   if (numWords > 256)
   {
      cout << "Error reading file " << fileName 
         << ". It has more than 256 words.";
      return 0;
   }
   fin.close();
   return numWords;
}

/**********************************************************************
*    The main function tells a program where to start.
***********************************************************************/
int main()
{
   char story[256][33];
   char fileName[256];
   getFilename(fileName);
   int wordCount = readFile(story, fileName);
   return 0;
}

Test output is now:

a.out:

------------------------------------------------------------
Starting Test 1

This first test is trivial, reading the following file:
My pet cat is very <{> <adjective> . <}> <#> So is my dog . <#>
There is one prompt: "adjective" which needs to turn to "\tAdjective: "

> Please enter the filename of the Mad Lib: /home/cs124/projects/madLibTrivial.txt
> \tA:
Exp: \tAdjective:
happy
>
Exp: Thank you for playing.\n

Test 1 failed.
------------------------------------------------------------

------------------------------------------------------------
Starting Test 2

This second test has 13 prompts. The file is:
I feel like yelling <{> <web_site_name> <}> every time I <verb> the <#>
Internet . So many <plural_noun> to look for , so many <plural_noun>
to find . <#> <#> My mother asked me , <{> <proper_noun> , what is so
<adjective> about <#> the Web ? <}> <{> Well , <}> I said , <{> just
the other day I did a search for <noun> <#> by entering <[> <noun>
<boolean_operator> <noun> <]> in a search <#> engine . And it returned
<favorite_website> and <another_website> . It's <#> just so <adjective>
! <}> <#> <#> And then she knew what I meant . I felt so happy ! <#>

> Please enter the filename of the Mad Lib: /home/cs124/projects/madLibWeb.txt
> \tW:
Exp: Web site name:
Automobile Magazine.com
> \tV: \tP:
Exp: Verb:
drive
> \tP:
Exp: Plural noun:
cars
> \tP:
Exp: Plural noun:
motorcycles
> \tA:
Exp: Proper noun:
New York
> \tN: \tN:
Exp: Adjective:
red
> \tB:
Exp: Noun:
Porsche
> \tN:
Exp: Noun:
BMW
> \tF:
Exp: Boolean operator:
xor
> \tA:
Exp: Noun:
Ferrari
> \tA:
Exp: Favorite website:
Car and Driver
>
Exp: Another website:
Ferrari.it
The 'else' at line 33 is redundant, because the 'if'-statment at line 31 filters all non-matching words out.
Also it seems that you have a misunderstanding about the story[] argument of 'askQuestions()' so far it is now, it will take a single word an not the whole story (which would be a two-dimensional array). So you could make 'askQuestion()' so, that it would process single word, but then you have to iterate over the who two dimensional story[][] array. Or you pass a two-dimensional array into 'askQuestions'. Or, you handle the two dimensional array like an one-dimensional array.

Here a suggestion how to iiterate over the two-dimensional 'story[][]'array. It's basically the same like your 'askQuestions()' code, but now it should work correctly with the two-dimensional story array.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* AskQuestion() will iterate over a two-dimensional array.
   The first dimension represents the words and the 2nd
   dimension represents the characters of a word.
   After the last word the array needs an 'end' mark, it should be the '\0' character.
*/ 
void askQuestions(char story[][])
{
    // iterates over each word in 'story'
    for (int i=0; story[i][0] != '\0' && i<256; ++i)
    {
        if (story[i][0] != '<' || !isalpha(story[i][1]))
           continue;   // Processes immediately the next loop turn.
           
        cout << "\t";
        story[i][1] = toupper(story[i][1]);
        cout << story[i][1];
        for (int iStory = 1; story[i][iStory] == '>'; iStory++)
        {
          if (story[i][iStory] == '_')
               cout << " ";
          else
          {
              story[i][iStory] = tolower(story[i][iStory]);
              cout << story[i][iStory];
          }
      }
      cout << ": ";
      cin >> story;
   }
}
Pages: 12