CSCI-15 Assignment #2, String processing. (60 points) Due 9/23/13

You MAY NOT use C++ string objects for anything in this program.

Write a C++ program that reads lines of text from a file using the ifstream getline() method, tokenizes the lines into words ("tokens") using strtok(), and keeps statistics on the data in the file. Your input and output file names will be supplied to your program on the command line, which you will access using argc and argv[].

You need to count the total number of words, the number of unique words, the count of each individual word, and the number of lines. Also, remember and print the longest and shortest words in the file. If there is a tie for longest or shortest word, you may resolve the tie in any consistent manner (e.g., use either the first one or the last one found, but use the same method for both longest and shortest). You may assume the lines comprise words (contiguous lower-case letters [a-z]) separated by spaces, terminated with a period. You may ignore the possibility of other punctuation marks, including possessives or contractions, like in "Jim's house". Lines before the last one in the file will have a newline ('\n') after the period. In your data files, omit the '\n' on the last line. You may assume that the lines will be no longer than 100 characters, the individual words will be no longer than 15 letters and there will be no more than 100 unique words in the file.

Read the lines from the input file, and echo-print them to the output file. After reaching end-of-file on the input file (or reading a line of length zero, which you should treat as the end of the input data), print the words with their occurrence counts, one word/count pair per line, and the collected statistics to the output file. You will also need to create other test files of your own. Also, your program must work correctly with an EMPTY input file – which has NO statistics.

My test file looks like this (exactly 4 lines, with NO NEWLINE on the last line):

the quick brown fox jumps over the lazy dog.
now is the time for all good men to come to the aid of their party.
all i want for christmas is my two front teeth.
the quick brown fox jumps over a lazy dog.

Copy and paste this into a small file for one of your tests.

Hints:

Use a 2-dimensional array of char, 100 rows by 16 columns (why not 15?), to hold the unique words, and a 1-dimensional array of ints with 100 elements to hold the associated counts. For each word, scan through the occupied lines in the array for a match (use strcmp()), and if you find a match, increment the associated count, otherwise (you got past the last word), add the word to the table and set its count to 1.

The separate longest word and the shortest word need to be saved off in their own C-strings. (Why can't you just keep a pointer to them in the tokenized data?)

Remember – put NO NEWLINE at the end of the last line, or your test for end-of-file might not work correctly. (This may cause the program to read a zero-length line before seeing end-of-file.)

This is not a long program – no more than about 2 pages of code.

Here is my solution:

#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
using namespace std;

int main(int argc, char *argv[])
{   
    ifstream inputFile;
    ofstream outputFile;
    char inFile[12] = "string1.txt";
    char outFile[16] = "word result.txt";
    char words[100][16]; // Hods the unique words.
    int counter[100]; // Holds associated counts.
    char *longest[16]; // Holds longest words.
    char *shortest[16]; // Holds shortest words.
    int totalCount = 0; // Counts the total number of words.
    int lineCount = 0; // Counts the number of lines.

    totalCount = strtok(words, "."); // Tokenizes each word and removes period.

    // Get the name of the file from the user.
    cout << "Enter the name of the file: ";
    getline(cin, inFile);

    // Open the input file.
    inputFile.open(inFile);

    // If successfully opened, process the data.
    if(inputFile)
    {
        while(!inputFile.eof())
        {
            lineCount++; // Increment each line.
            // Read every word in each line.
            while(getline(inFile, words[100][16]))
            {
                // If there is a match, increment the associated count.
                if(strcmp(words[100][16], counter[100]) == 0)
                {
                    counter[100]++;
                    totalCount++; // Increment the total number of words;
                    totalCount = strtok(NULL, " "); // Removes the whitespace.
                    // If there is a tie for longest word, get the first or last word found.
                    if(strcmp(inFile, longest) == 0)
                    {
                        longest[16] = "";
                    }
                    // If there is a tie for shortest word, get the first or last word found.
                    else if(strcmp(inputFile, shortest) == 0)
                    {
                        shortest[16] = "";
                    }
                }
                // Otherwise, add the word to the table and increment by 1.
                else
                {
                    words[100][16] += 1;
                }
            }
        }
        // Close the file.
        inputFile.close();
    }
    // Otherwise, print error message.
    else
    {
        cout << "Cannot open the file" << endl;
    }

    // Open the output file.
    outputFile.open(outFile);
    // Print the table to the output file.
    outputFile << "List of words: " << endl;
    outputFile << "---------------------" << endl;

    // Print each word/count pair per line.
    for(int i = 0; i < words[100][16]; i++)
    {
        outputFile << setw(10) << words[i][16] << endl;
        outputFile << setw(10) << words[100][i] << endl;
    }
    outputFile << endl;
    // Print the stats to the output file.
    outputFile << "Number of Lines: " << lineCount << endl;
    outputFile << "Total number of Words: " << totalCount << endl;
    outputFile << "Number of Unique Words: " << words[100][16] << endl;

    // Close the output file.
    outputFile.close();

    return 0;
}

Right now, my code has a few errors and I'm not sure how to fix them. Is there anything I need to change?

andrew.mendonca.967
Deleted Member

line 20: cannot convert char[][16] to char for argument 1 to char strtok[char, const char)
line 24: no matching function for call to getline[std:istream&, char[12]]
line 36: no matching function to call to getline[char[12], char&]
line 39: invalid conversion from char to const char
line 39: invalid conversion from int to const char
line 43: invalid conversion from char to int
line 45: cannot convert char to const char for argument 2 to int strcmp[const char, const char]
line 50: cannot convert std:ifstream to const char for argument 1 to int strcmp[const char, const char]

Review the instructions to your assignment. Sometimes are error is not the coding itself but the failure to follow instructions.

Like this:

...data in the file. Your input and output file names will be supplied to your program on the command line, which you will access using argc and argv[]

...but in line 23 you asked the user to enter the input file.

Of course, there are still other errors in your code (like line 20(?)) but review--and understand well--your instruction and rewrite your code and try to compile and run it so that you yourself can see the problem. It is the compiler's task to inform us the errors (except of course logical errors) and it is our task to fix them. If your compiler tells about errors, try to understand them first and fix them yourself until you prove to yourself you need the others' help. That way, I suppose, you will learn programming systematically.

This question has already been answered. Start a new discussion instead.