# Now that I pretty much understand the basics of C++...



## InterKnight (Oct 19, 2004)

Well, it was a challenging road, somewhat, but I have a good understanding of the basics of C++. The only problem I am having now is understanding the riddles of my professor in the assignments he gives out. I have really appreciated all of the help given to me from all of you here...It's truly helped me through. I now have an assignment that deals with string manipulation for my course. I know how to check characters entered to strings and such, but I don't know what our professor wants from us. The dropout rate for this course is IMMENSE. It started out with 25 students, and now there are only four of us left. And the professor seems to love to brag about his buckets of red ink and such for grading...kind of makes things stressing. I've showed my uncle the specs for this final assignment, but even he isn't completely sure exactly what is needed...Can any of you give me a bit of advice? I would really appreciate it. Below are the parts of this assignment. Thanks in advance for any help that is offered.

1) This is an exercise in implementing error checking. In your main(), initialize the following variables:

int inum, iArray[5];

float fnum, fArray[5];

char letter, lArray[10];

Then ask the user to enter values into the inum, fnum, and letter. Your program should have functions to reject keyboard entries of inappropriate characters. If the program calls for entering a value into inum, the input should be checked by a function whose sole purpose is to be sure what was entered was an integer. This check should be made before the value is assigned to inum. The function should then use a pointer to assign the checked value to inum. If the program calls for entering a value into fnum, then the value should be checked to see that it is a floating point number. The general form of a float is:

[whitespace] [sign] [digits] [. digits] [ {d | D | e | E }[sign]digits]

A whitespace consists of space and/or tab characters, which are ignored; sign is either plus (+) or minus ( ? ); and digits are one or more decimal digits. If no digits appear before the decimal point, at least one must appear after the decimal point. There can be the notation D or E indicating an exponent, but ignore that fact for this assignment.

As a minimum, check to see that

a) Only digits, decimal points, or a + or - sign have been entered;

b) Only one decimal point has been entered;

c) The + or - occurs as the first character after any whitespace

For iarray[] and farray[], only the appropriate data type should be accepted (use the functions developed in the paragraph above to do this), and only the "legal" subscripts for the five array values should be accepted when entering data into or retrieving data from the arrays. Use functions that check the subscript that was entered to assign and retrieve values from the arrays. The arrays should be passed to their respective checking and data-altering functions.

For the 10-element lArray[], the user should enter a string as input. You should make a function that only allows a maximum of nine characters to be entered into this array, and which automatically adds the terminating NULL after the last character entered. In other words, your function should make lArray[] into a C++ string. (Be careful! The user may enter less than 9 total characters, so don't just automatically put the Null as the last array element.) Do not use any built-in string-getting functions such as getline() or gets(). Build this function from scratch. Of course, you will pass the lArray[] to this function. Only upper case letters should appear in the final string, no matter what the case of the original characters entered was.

2) Write a program that uses a random number generator to create sentences. The program should use four arrays of pointers to char called article[], noun[], verb[], and preposition[]. The program should create a sentence by selecting a word at random from each of the arrays in the following order: article[], noun[], verb[], preposition[], article[], noun[]. As each word is picked, it should be concatenated to the previous words in an array which is large enough to hold the entire sentence. The words should be separated by spaces. When the final sentence is output, it should start with a capital letter and end with a period.

The arrays should be filled as follows: article[] should contain "the", "a", "one", "some", and "any"; noun[] should contain "boy", "girl", "dog", "town", and "car"; verb[] should contain "drove", "jumped", "ran", "walked", and "skipped"; and preposition[] should contain "to", "from", "over", "under", and "on".

After the program is written and working, modify the program to produce a short story of twenty non-repeating sentences. Occasionally add a random "However", "But", "Then" or other conjunction to make the story flow. You might want to make a second copy of this program and change the words to computer or science terms and make a random term paper writer.


----------



## Arcadion (Sep 2, 2004)

Gawd, that's mean. I've written programs to do this kind of thing, but in the 4th (final) year of a computer science degree, not in a beginning course. Your prof is a psychopath.


----------



## InterKnight (Oct 19, 2004)

It doesn't seem like it would be too difficult...it is just that I don't know exactly what the professor wants. He likes to keep us challenged and to make us think, but sometimes I think there is a little much...


----------



## Arcadion (Sep 2, 2004)

Well for a start you need to write a parser (program that reads the input and checks that it's ok) -- the easiest way to do this is using the programs flex and bison/yacc, writing one in C++ is just going to be messy, as you have to code the finite state automaton yourself. Has he shown you FSAs? They're like flowcharts with a series of states and transitions between states, depending on what character is currently being processed. This is standard compsci theory.


----------



## Shadow2531 (Apr 30, 2001)

For the first part, you can use a method something like this:


```
#include <iostream>

using namespace std;

int getInt() {
    int good_value;
    
    enter loop and ask for input
    (use a char array since you can't use the string class and getline() )
    
    check that the input is valid. If it is not, ask for the input again

    return good value; // you always end up with a good value
}

int main() {
    int i = getInt();
}
```
You can make another function then for floats. (no need to make one function do them both for starters). You can then use those functions to build the array of floats and array of ints.

Then a similar method could be used for the char array, but use function of type void().

There are plenty of better ways to do this stuff, but from your description, you have to do it using c-like methods.

I have a getInt() function laying around somewhere. I'll have to find it. It looks sloppy compared to using boost::regex though.


----------



## InterKnight (Oct 19, 2004)

Thanks.

I guess we are able to use <iostream.h>, <string.h>, <iomanip.h>, <stdlib.h>, <ctype.h>, and a few others. What I did for the integer check was set up a char array and have the user place input directly into it, then I placed the array into a for() loop and checked the values using isalpha(), ispunct(), and a few other things. Then what I was going to do was use one of the arguments for the function to send back the integer value to an int variable in main()...like...

int main()
{
int inum;
}

void checkint(int &inum)
{
char intarray[];

inum = atoi(intArray);
}

That is basically, from what I do know, what he wants. And for the fnum I could use the same kind of method, except using atof() rather than atoi(). Then what I thought about doing was setting up a for loop to initialize the arrays in main. One for iArray, one for fArray, and one for the final char array. And in each for loop I could get the value for each element by returning it from the checkint, float, and char functions. I think that that would work.

I guess everyone is having problems with that random sentence generator. I'm just doing the best I can...

Thanks for the input.


----------



## Shadow2531 (Apr 30, 2001)

Looks like you have the basic idea.

For the sentence generator, I assume you know how to initalize the arrays with the predetermined values. If not, here's an example that also uses a loop to print out all of the entries.


```
#include <iostream>

using namespace std;

int main() {
    const char* article[]     = {"the"  , "a"     , "one" , "some"   , "any"    }; 
    const char* noun[]        = {"boy"  , "girl"  , "dog" , "town"   , "car"    };
    const char* verb[]        = {"drove", "jumped", "ran" , "walked" , "skipped"};
    const char* preposition[] = {"to"   , "from"  , "over", "under"  , "on"     };
    
    for (size_t i = 0; i < 5 ; ++i) {
        cout << article[i]     << "\n"
             << noun[i]        << "\n"
             << verb[i]        << "\n"
             << preposition[i] << endl;
    }
}
```
Instead of printing out all of them, try to randomly print out positions to make a sentence.

Then. after you get that part done, you can add to an array instead of printing out and only print out the full sentence from the array.

You just need an array large enough to hold a sentece and you need to be able concatenate the different parts of the sentence into the array.

Here's an old post on random numbers that might help.
http://forums.techguy.org:80/t267021

Basically, you need to get a VAILID random position of each of the arrays to build a sentence. Since what's in the arrays is constant, you can use the know size of each array (which is the same for each one) as the limit of your random number.

The random number produced, each time you need one, should be 0,1,2,3 or 4 as those are valid positions in each of the array of pointers.


----------



## Shadow2531 (Apr 30, 2001)

As an example, here's how you could build the sentence manually. (You need to do it where the parts are random, so this is just an example to get your started.)


```
#include <iostream>
#include <cstring> // wrapper for c header: string.h - strcat()  lives here under the std namespace
#include <cctype>  // wrapper for c header: ctype.h  - toupper() lives here under the std namespace

using namespace std;

int main() {
    
    // Declare and initialize each array of char pointers
    // Not going to be changed, so make const
    const char* article[]     = {"the"  , "a"     , "one" , "some"  , "any"    }; 
    const char* noun[]        = {"boy"  , "girl"  , "dog" , "town"  , "car"    };
    const char* verb[]        = {"drove", "jumped", "ran" , "walked", "skipped"};
    const char* preposition[] = {"to"   , "from"  , "over", "under" , "on"     };
    
    // Delcare an array of chars to hold the sentence. Choose a size large enough.
    // Must initialize the array first before adding things to it.
    char sentence[250] = "";
    
    // Build sentence by concatenating the sentence with each part.
    strcat(sentence, article[0]);
    strcat(sentence," ");
    strcat(sentence,noun[1]);
    strcat(sentence," ");
    strcat(sentence,verb[1]);
    strcat(sentence," ");
    strcat(sentence,preposition[2]);
    strcat(sentence," ");
    strcat(sentence,article[1]);
    strcat(sentence," ");
    strcat(sentence,noun[2]);
    strcat(sentence,".");
    
    // Change the first letter of the sentence to upper case
    sentence[0] = toupper(sentence[0]);
    
    // Print out sentence.
    cout << sentence << endl; // endl = \n + flushes the stream buffer
    
}
```
That should help.

That's a basis of how you'd probably have to do it since you are not allowed to use the string class.

Just for kicks, if you were allowed to use the string class, you could do the same thing like this:


```
#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main() {
    
    const string article[]     = {"the"  , "a"     , "one" , "some"  , "any"    }; 
    const string noun[]        = {"boy"  , "girl"  , "dog" , "town"  , "car"    };
    const string verb[]        = {"drove", "jumped", "ran" , "walked", "skipped"};
    const string preposition[] = {"to"   , "from"  , "over", "under" , "on"     };
    
    string sentence = article[0] + " " + 
                         noun[1] + " " + 
                         verb[1] + " " + 
                  preposition[2] + " " + 
                      article[1] + " " + 
                         noun[2] + "." ;

    sentence[0] = toupper(sentence[0]);
    
    cout << sentence << endl;
    
}
```


----------



## InterKnight (Oct 19, 2004)

Thanks for all of the input. I finally got both of the programs working. I got a good laugh out of the sentence generator. I am posting the code below so taht anyone who reads on can see what I did. It works flawlessly. I just created functions for the article, moun, verb, preposition, and conjunction. This comes up wiht some pretty hilarious sentences. I am just glad that it is done, though. I just wanted to thank you all again for your help; you definitely helped me get a good start and a passing grade. The quarter ends next week, and this was our last major assignment.
Thanks again.

Here is my code for the sentence generator (sorry for the spacing issues. I'm not sure how to post code as all of you do.):

#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>

void article(char []);
void noun(char []);
void verb(char []);
void preposition(char []);
void conjunction(char []);

int main() 
{
srand(time(0));

char sentence[250] = "";

for (int i = 0; i <= 20 ; ++i) 
{
if((rand() % 21) > (i + 2))
conjunction(sentence);

article(sentence);
strcat(sentence," ");
noun(sentence);
strcat(sentence," ");
verb(sentence);
strcat(sentence," ");
preposition(sentence);
strcat(sentence," ");
article(sentence);
strcat(sentence," ");
noun(sentence);
strcat(sentence,".");

sentence[0] = toupper(sentence[0]);
cout << sentence << endl;
strcpy(sentence,"");
}

return 0;
}

void article(char sentence[])
{
const char *article[] = {"the","a","one","some","any"};

strcat(sentence,article[rand() % 5]);
}//End article()

void noun(char sentence[])
{
const char *noun[] = {"boy","girl","dog","town","car"};

strcat(sentence,noun[rand() % 5]);
}//End noun()

void verb(char sentence[])
{
const char *verb[] = {"drove","jumped","ran","walked","skipped"};

strcat(sentence,verb[rand() % 5]);
}//End verb()

void preposition(char sentence[])
{
const char *preposition[] = {"to","from","over","under","on"};

strcat(sentence,preposition[rand() % 5]);
}//End preposition()

void conjunction(char sentence[])
{
const char *conjunction[] = {"but","however","suddenly","then","also","alas"};

strcat(sentence,conjunction[rand() % 6]);
strcat(sentence,",");
strcat(sentence," ");
}//End conjunction()


----------



## Shadow2531 (Apr 30, 2001)

Congrats.

I had this commented example sitting around for when you showed effort. Since you already figured it out, you don't actually need it, but there are some points it makes.


```
/* Randomly Generated Sentence in ISO C++ using C methods */

#include <cstdio>  // wrapper for c header: stdio.h  - printf()  lives here under the std namespace
#include <cstring> // wrapper for c header: string.h - strcat()  lives here under the std namespace
#include <cctype>  // wrapper for c header: type.h   - toupper() lives here under the std namespace
#include <ctime>   // wrapper for c header: time.h   - time()    lives here under the std namespace
#include <cstdlib> // wrapper for c header: stdlib.h - srand() and rand() live here under the std namespace

using namespace std; // use std namespace below for any of its members instead of prepending std:: to each of them


// main() must have a non-void type. 
// Also, if command-line arguments are not needed, use 'int main()' instead of 'int main(void)'.

int main() {
    
    // Declare and initialize each array of char pointers
    // Not going to be changed, so make constant
    const char* article[]     = {"the"  , "a"     , "one" , "some"  , "any"    }; 
    const char* noun[]        = {"boy"  , "girl"  , "dog" , "town"  , "car"    };
    const char* verb[]        = {"drove", "jumped", "ran" , "walked", "skipped"};
    const char* preposition[] = {"to"   , "from"  , "over", "under" , "on"     };
    
    // Declare an array of chars to hold the sentence. Choose a size large enough. 
    // Must initialize the array first before adding things to it.
    char sentence[50] = ""; // Size should be 42 or greater
    
    srand(time(0)); // Use current time as seed value for rand() calculations
    
    // Build sentence by concatenating the sentence with each part.
    // Array position is random value: 0 or 1 or 2 or 3 or 4
    strcat(sentence, article[ rand() % 5 ] );
    strcat(sentence, " " );
    strcat(sentence, noun[ rand() % 5 ] );
    strcat(sentence, " " );
    strcat(sentence, verb[ rand() % 5 ] );
    strcat(sentence, " " );
    strcat(sentence, preposition[ rand() % 5 ] );
    strcat(sentence, " " );
    strcat(sentence, article[ rand() % 5 ] );
    strcat(sentence, " " );
    strcat(sentence, noun[ rand() % 5 ] );
    strcat(sentence, "." );
    
    // Change the first letter of the sentence to upper case
    sentence[0] = toupper(sentence[0]);
    
    // Print out sentence.
    printf("\n%s\n", sentence);

    // return 0; is not needed at the end of main() in c++.
    
}
```


----------

