Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Program1 For this assignment, you need to write only one source code file, assig

ID: 3628425 • Letter: P

Question

Program1

For this assignment, you need to write only one source code file, assign1.cpp. You will need to #include a variety of header files: (for output to the console), (for output formatting), (for file input), (for character tests and case conversion), and (for the C string library functions). You will also need using declarations for any C++ library items from the standard namespace that you use in your code (ifstream, cout, various output manipulators, etc.).

Symbolic Constants

At the top of your program (after the #includes and usings but before your function prototypes or main() function), declare a couple of symbolic constants. Define WORD_LENGTH as 20 and ARRAY_SIZE as 500.

The main() Function

In your main() function, you should declare the following variables:

• An input file stream variable to read character data from a file. I'll refer to this variable from this point on as inFile.

• An array of ARRAY_SIZE C strings. Declare the array the same way you would declare a two-dimensional array of characters, with ARRAY_SIZE rows and WORD_LENGTH+1 columns in each row. I'll refer to this variable as wordArray. It will be used to store words you read from the input file.

• An array of ARRAY_SIZE integers. All of these integers should be initialized to 0. I'll refer to this variable as wordCountArray. It will be used to store the counts for words you read from the input file. This array can be considered to be "parallel" with wordArray - element 0 of wordCountArray is the count for the word stored in element 0 of wordArray, element 1 of wordCountArray is the count for the word stored in element 1 of wordArray, and so forth.

• An integer to track the number of words read from the input file that are stored in the wordArray (as well as the number of counts maintained in wordCountArray). The variable should be initialized to 0. I'll refer to this variable as numWords.

• A C string (array of char) of WORD_LENGTH+1 characters. This string will hold a word read from the input file. I'll refer to this variable originalWord.

• A C string (array of char) of WORD_LENGTH+1 characters. This string will hold a word from the input file that has had all of its leading and trailing punctuation removed. I'll refer to this variable as cleanedWord.

Start by opening your input file stream using the file name words.txt. Test whether the file was opened successfully. If not, print an error message to that effect and exit the program.

Next, you need to read a word from the file. Since the words in the input file are separated by whitespace, we can use the >> to read a word. You might be tempted to try to read the word directly into your wordArray, but this is a bad idea (for reasons described below).

Obviously, the file probably contains more than one word, so we'll need a loop that will keep reading words and processing them until we run out of words (i.e., until we reach the end of the file).

There are a couple of ways to test for the end of file condition in C++. One of the easiest is to simply test the state of your file stream variable, like this:

inFile >> originalWord;

while (inFile)

{

// Not at end of file, so go ahead and process the word we read



inFile >> originalWord;

}

As long as there are more words to read, inFile will resolve to true. If we reach end of file, or some error happens with the file stream that prevents us from reading any further, inFile will resolve to false, terminating the loop. Note that we need a read statement before the loop condition as well as another read statement at the very bottom of the loop body.[1][2]

Inside the loop, you need to process the originalWord you just read.

First, you need to remove any punctuation at the beginning or end of the word.[3] Call the function removePunctuation(), passing it originalWord and cleanedWord.

It's theoretically possible (although unlikely) that the word you read contained nothing but punctuation, with no actual text. If so, cleanedWord will contain a "null" or empty string of length 0. You don't want to count such a "word", so the remaining steps in the loop body (except for reading the next word!) should be skipped if the length of cleanedWord is 0.[4]

Next, you need to convert all of the characters in the string cleanedWord to upper-case. This will ensure that capitalization in the input file does not throw off your word counts (for example, the words "The" and "the" should be considered the same word for counting purposes).

Loop through the elements of the array cleanedWord until you reach the end of the string (signified by the null character ''). For each array element, call the function toupper(), passing it the array element. Store the return value from the toupper() function back into the array element that you passed to it.

Next, you need to determine whether this word already exists in your wordArray (in which case all you need to do is add one to its count), or whether it is a new word that must be added to the array (with a count of 1). You should also account for the possibility that this is a new word but that your wordArray is already full. In practice, this should not happen, but it's certainly possible with a fixed-size array.

Call the searchForWord() function, passing it wordArray, numWords, and cleanedWord. Store the integer the function returns in a variable (which I'll refer to as index). You need to test the value of index. There are three possible cases that need to be addressed.

1. If index is greater than or equal to ARRAY_SIZE, then this is a new word, but your wordArray is already full. Print an error message to that effect.

(Note: index should never be greater than ARRAY_SIZE, unless you made a mistake elsewhere in your code. But accounting for the possibility is a good example of defensive programming. Better to print an error message than overflow an array and corrupt your program's memory!)

2. Otherwise, if index is equal to numWords, then this is a new word that needs to be inserted into the array and index is the empty array element at which to insert. Copy cleanedWord into element index of wordArray[5] and set element index of wordCountArray to 1. Also add 1 to numWords.

3. Otherwise, this word already exists in the array at element index. Add 1 to element index of wordCountArray.

The word you read should now have been processed successfully. Remember to read the next word at the botton of the loop. Otherwise, you get an infinite loop that keeps counting the same word over and over!

Once you've reached end of file (and your read loop has terminated), go ahead and close the input file stream.

Next, call the sortWords() function, passing it the wordArray, the wordCountArray, and numWords. This should sort the words and their associated counts in ascending alphabetic order.

Finally, call the printWords() function, passing it the wordArray, the wordCountArray, and numWords. This should print out the words and their associated counts.

Other Functions

In addition to main(), you should write the following functions. Prototypes for these functions should be placed before main(). Definitions for the functions should be placed after main(). You may code the functions in any order, but the order should match the order in which your prototypes are listed (not required by the compiler, but good programming practice).

• removePunctuation()

This function should take two parameters: 1) a character array containing a word with punctuation to remove (originalWord), and 2) a character array (or pointer to a character in an array) to hold the word with its punctuation removed (cleanedWord). The function should return nothing.

This function should remove any leading or trailing punctuation. Pseudocode for the function is given below:

int start = 0, newStart = 0;

int end = length of originalWord - 1



// See Programming Note [6]

while (element start of originalWord is not alphanumeric and start is less than or equal to end)

Add 1 to start



while (element end of originalWord is not alphanumeric and end is greater than or equal to zero)

Subtract 1 from end



while (start is less than or equal to end)

{

Copy element start of original word to element newStart of cleanedWord

Add 1 to both start and newStart

}



Set element newStart of cleanedWord to a null character

• searchForWord()

This function should take three parameters: 1) an array of C strings (the wordArray), 2) an integer specifiying the number of words stored in the wordArray (numWords), and 3) a character array containing the word to search for (cleanedWord). The function should return an integer.

The logic for this function is a variation of the linear search of a list strategy.

int i;



// Loop through words stored in wordArray

for (i = 0; i < numWords; i++)

{

// See Programming Note [7]

if (cleanedWord is equal to wordArray[i])

break;

}



if (i == ARRAY_SIZE) // Word was not found and wordArray is full

return -1; // Return error signal

else

return i; // Return index of word found or empty slot

• sortWords()

This function should take three parameters: 1) an array of C strings (the wordArray), 2) an array of integers (the wordCountArray), and 3) an integer specifiying the number of words stored in the wordArray (numWords). The function should return nothing.

This function should sort the words in wordArray (and their corresponding counts in wordCountArray) in ascending order using the selection sort algorithm.

The sort code linked to above sorts an array of integers called numbers of size size. You will need to make a substantial number of changes to that code to make it work in this program:

1. Change the parameters for the function to those described above.

2. In the function body, change the name temp to countTemp. This temporary storage will be used to swap elements of wordCountArray.

3. Add an additional temporary storage variable, wordTemp. Declare it as an array of characters of size WORD_LENGTH+1. This temporary storage will be used to swap elements of wordArray.

4. In the function body, change any occurrence of numbers to wordArray and size to numWords.

5. The comparison of wordArray[j] and wordArray[min] will need to use the C string library function strcmp() to perform the comparison.

6. The three lines of code that swap array elements min and i will need to be replaced. You will need to use three lines to swap wordCountArray[min] and wordCountArray[i] using the integer countTemp as temporary storage. You will also need three lines of code to swap wordArray[min] and wordArray[i] using the character array wordTemp as temporary storage. This swap can not be done using assignment statements; you'll need to use the C string library function strcpy() to do the copying.

• printWords()

This function should take three parameters: 1) an array of C strings (the wordArray), 2) an array of integers (the wordCountArray), and 3) an integer specifiying the number of words stored in the wordArray (numWords). The function should return nothing.

This function should print out a descriptive header message (e.g., "Word Counts for words.txt"), then loop through the wordArray and wordCountArray and print each word and its associated count. You can use cout and the << operator to do the printing. Print three words and their associated counts per line of output and use the setw, left, and right manipulators to justify the words and counts and align them into columns (see the sample output posted for what this should look like).

A simple and useful trick for printing a specific number of array elements per line is to divide your loop counter by the number of items per line that you want and go to a new line when the remainder is 0, e.g.:

if (i % 3 == 0)

cout << endl;



// Print array element i here

This code will go to a new line before the first item in the array is printed, before the fourth item is printed, before the seventh is printed, etc.

If you don't want a blank line before you start printing array elements, try the following instead:

// Print array element i here



if ((i+1) % 3 == 0)

cout << endl;

This will go to a new line after the third item item in the array is printed, after the sixth item, after the ninth, etc.

After you've printed all of the words in the wordArray and their counts, print the number of distinct words (the value of numWords).

Programming Notes

[1] Coding the read statement at the top of the loop body is a mistake, and will result in two different bugs in your program:

1. Until you've actually tried to read a word from the input file, the state of inFile is meaningless. It will resolve to true even if the input file contains no words. The only way to detect end of file is to attempt to read a word from the file and have the read fail.

2. When end of file is reached, we need to terminate the loop body immediately. Coding your read statement at the top of the loop body will not do this - your program will go ahead and execute the rest of the loop body before it gets around to testing whether or not end of file has been reached. This means you'll end up processing the last word in the file twice, which will throw off your count for that word.

[2] There is a shorthand way to code this loop in C++ that requires only one read, but the correct way to do this is non-obvious:

while (inFile >> originalWord)

{

// Not at end of file, so go ahead and process the word we read

}

This works because the expression inFile >> originalWord reads a word from the input file into the array and then returns the value of inFile to be tested as the loop condition.

[3] The >> operator definition of a "word" is "a sequence of non-whitespace characters delimited by whitespace". For example, if your read loop reads the following series of "words":

C is an imperative (procedural) systems implementation language.

you will end up with the following eight strings:

"C"

"is"

"an"

"imperative"

"(procedural)"

"systems"

"implementation"

"language."

As you can see, some of these "words" include punctuation, which will adversely affect counting them correctly.

[4] One way to check this is to use the C string library function strlen().

[5] An assignment statement will not work for this purpose - you can't assign one character array to another. Use the C string library function strcpy() instead.

[6] One way to determine whether or not a character is alphanumeric is to use the C library function isalnum().

[7] Character arrays containing C strings can not be compared using relational operators like == or <. Use the C string library function strcmp() to perform the comparison.

Other Points

• As always, programs that do not compile on turing/hopper automatically receive 0 points.

• Make sure to document your program according to the standards listed in the Course Notes book. In particular, each function should have a documentation box describing the purpose of the function, the input parameters, and the return value (if any). There should also be a documentation box for the program as a whole.

• Submit your program using the electronic submission guidelines posted on the course web site and described in class.







Explanation / Answer

please rate - thanks

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
#define WORD_LENGTH 20
#define ARRAY_SIZE 500
void removePunctuation(char[],char[]);
int searchForWord(char[][WORD_LENGTH+1],int,char[]);
void sortWords(char[][WORD_LENGTH+1],int[],int);
void printWords(char[][WORD_LENGTH+1],int[],int);
int main()
{int count[ARRAY_SIZE],i,counter=0,index;
char words[ARRAY_SIZE][WORD_LENGTH+1],word[WORD_LENGTH+1],cleanword[WORD_LENGTH+1];

ifstream in;
   in.open("words.txt");           //open file
   if(in.fail())             //is it ok?
       { cout<<"input file did not open please check it ";
        system("pause");
        return 1;
        }
for(i=0;i<ARRAY_SIZE;i++)
     count[i]=0;
in>>word;
while(in)
    {removePunctuation(word,cleanword);
    if(strlen(cleanword)!=0)
        {for(i=0;cleanword[i]!='';i++)
            cleanword[i]=toupper(cleanword[i]);
          index=searchForWord(words,counter,cleanword);
          if(index==-1)
                cout<<"array full ";
           else if(index==counter)
               {for(i=0;cleanword[i]!='';i++)
                    words[index][i]=cleanword[i];
                words[index][i]='';
                count[index]=1;
                counter++;
                }
            else
                count[index]++;  
            }
    in>>word;
         }

sortWords(words,count,counter);
printWords(words,count,counter);
in.close();
system("pause");
return 0;
}
void removePunctuation(char o[],char n[])
{int start = 0, newStart = 0;
int end = strlen(o) - 1;
while(!isalnum(o[start])&&start<=end)
     start++;
while(!isalnum(o[end])&&end>=0)
     end--;
while(start<=end)
     n[newStart++]=o[start++];
n[newStart]='';      
}
int searchForWord(char a[][WORD_LENGTH+1],int n,char w[])
{int i;
for(i=0;i<n;i++)
   if(strcmp(w,a[i])==0)
         break;
if (i == ARRAY_SIZE) // Word was not found and wordArray is full
     return -1; // Return error signal
return i;
        
}
void sortWords(char a[][WORD_LENGTH+1],int w[],int n)
{int t,i,j;
char ct[WORD_LENGTH+1];
for(i=0;i<n-1;i++)
      for(j=i;j<n;j++)
          if(strcmp(a[i],a[j])>0)
               {strcpy(ct,a[i]);
               strcpy(a[i],a[j]);
               strcpy(a[j],ct);
               t=w[i];
               w[i]=w[j];
               w[j]=t;
               }

}
void printWords(char a[][WORD_LENGTH+1],int w[],int n)
{cout<<"Word Counts for words.txt ";
int i;
for(i=0;i<n;i++)
              {cout <<setw(15)<<left<< a[i] << " " << w[i] << " |";
               if((i+1)%3==0)
                     cout<<endl;
              }
cout<<endl;
}