Member Avatar for andrew.mendonca.967

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.

#include<iostream>
#include<iomanip>
#include<fstream>
using std::cout;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::cin;
using std::getline;

// Print every unique word and its associated count
void uniquewords(char words[100], char uniqueWords[100][16], int position[100], int &counter)
{
    bool found = false; // Determines if word is found in the file.
    int i;

    for(i = 0; i < 100; i++)
    {
        // If there is a match, increment the word by 1.
        if(strcmp(words,uniqueWords[i]) == 0)
        {
            position[i] += 1;
            found = true;
        }
    }
    // If there is no match, add the word to the table and set its count to 1.
    if(found == false)
    {
        strcpy(uniqueWords[counter], words);
        position[counter] = 1;
        counter++; // Increment the total number of unique words in the file.
    }
}

// Find and print the longest and shortest words in the file.
void longestandshortestWord(char words[100], char longestword[100], char shortestword[16])
{
    static int length;
    static int longestlength = 0;
    static int shortestlength = 0;

    longestlength = strlen(longestword); // Determine which word is longer.
    shortestlength = strlen(shortestword); // Determine which word is shorter.
    length = strlen(words); // Determine length of each word.
    // If one word is longer than the others, get the longest word.
    if(length > longestlength)
    {
        longestlength = length;
        strcpy(longestword, words);
    }
    // If one word is shorter than the others, get the shortest word.
    else if(length < shortestlength)
    {
        shortestlength = length;
        strcpy(shortestword, words);
    }
}

int main(int argc, char *argv[])
{
    ifstream inputFile;
    ofstream outputFile;
    char *token;
    char words[100]; // Holds every word.
    char uniqueWords[100][16]; // Holds the unique words.
    bool firsttime = true;
    int totalnumWords = 0;
    int linecount = 0;
    int uniquewordcounter = 0;
    char longestword[100]; // Holds the longest word.
    char shortestword[16]; // Holds the shortest word
    char lines[100];
    int position[100]; // Holds the associated counts.
    char inFile[12] = "string1.txt";
    char outFile[16] = "word result.txt";

    // Get the name of the file from the user.
    cout << "Enter the name of the file: ";
    cin >> inFile;

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

    // Open the output file.
    outputFile.open(outFile);

    // If the function is called the first time, search every word in the file.
    if(firsttime)
    {    
        for(int i = 0; i < 100; i++)
        {
            position[i] = -1;
        }
        firsttime = false;
    }
    // If successfully opened, process the data.
    if(inputFile)
    {   
        while(inputFile.getline(words,100))
        {
            // Read each word.
            linecount++;            
            token = strtok(words, " .\n");
            while(token != NULL)
            {
                token = strtok(NULL, " .\n");
                totalnumWords++; // Increment the total number of words in the file.
                longestandshortestWord(words, longestword, shortestword);
                uniquewords(words, uniqueWords, position, uniquewordcounter);
            }
        }
        outputFile << "Words/Count" << endl;
        outputFile << "------------" << endl;
        // Print each unique word and its associated count.
        for(int i = 0; position[i] != -1; i++)
        {
            token = strtok(uniqueWords[i], " .\n");
            outputFile << uniqueWords[i] << ": " << position[i] << endl;
        }
        // Display the total number of lines, unique words, and words in the file.
        outputFile << "Total number of lines in file: " << linecount << endl;

    outputFile << "Total number of unique words in file: " << uniquewordcounter << endl;
        outputFile << "Total number of words in file: " << totalnumWords << endl;
        outputFile << "Longest word: " << longestword << endl;
        outputFile << "Shortest word: " << shortestword << endl;
        // Close the input file.
        inputFile.close();
        // Close the output file.
        outputFile.close();
    }
    else
    {
        // Display the error message.
        cout << "There was an error opening the input file.\n";
    }

    return 0;
}

Because of this piece of code:

while(inputFile.getline(words,100))
        {
            // Read each word.
            linecount++;            
            token = strtok(words, " .\n");
            while(token != NULL)
            {
                token = strtok(NULL, " .\n");
                totalnumWords++; // Increment the total number of words in the file.
                longestandshortestWord(words, longestword, shortestword);
                uniquewords(words, uniqueWords, position, uniquewordcounter);
            }
        }

I'm getting this output:

Words/Count 
------------ 
the: 18 
now: 16 
all: 10 
Total number of lines in file: 4 
Total number of unique words in file: 3 
Total number of words in file: 44 
Longest word: €T@ 
Shortest word: ðþ" 

Before using that piece of code, it used to be this:

linecount++;
    while(!inputFile.eof())
    {
        inputFile >> words; // Read each word.
        totalnumWords++; // Increment the total number of words in the file.
        uniquewords(words, uniqueWords, position, uniquewordcounter);
        longestandshortestWord(words, longestword, shortestword);
    }

And I was getting this output:

Words/Count 
------------ 
the: 5 
quick: 2 
brown: 2 
fox: 2 
jumps: 2 
over: 2 
lazy: 2 
dog: 2 
now: 1 
is: 2 
time: 1 
for: 2 
all: 2 
good: 1 
men: 1 
to: 2 
come: 1 
aid: 1 
of: 1 
their: 1 
party: 1 
i: 1 
want: 1 
christmas: 1 
my: 1 
two: 1 
front: 1 
teeth: 1 
a: 1 
Total number of lines in file: 1 
Total number of unique words in file: 29 
Total number of words in file: 44 
Longest word: christmas 
Shortest word: i 

My question is: How can I read the total number of lines in the file without affecting my other output? I'm having a lot of trouble with getting the number of lines. That is the only part I need help with.

You need to process each word (token).

while (inputFile.getline(words, 100))
{
    // Read each word.
    linecount++;
    token = strtok(words, " .\n");

    while(token != NULL)
    {
        // process each token
        longestandshortestWord(token, longestword, shortestword);
        uniquewords(token, uniqueWords, position, uniquewordcounter);
        token = strtok(NULL, " .\n");
        totalnumWords++; // Increment the total number of words in the file.              
    }            
}

Any discrepancies in the results can be overcome by initialising the relevant variables declared at the top of main(...).

If done correctly, your output will be:

Words/Count
------------
the: 5
quick: 2
brown: 2
fox: 2
jumps: 2
over: 2
lazy: 2
dog: 2
now: 1
is: 2
time: 1
for: 2
all: 2
good: 1
men: 1
to: 2
come: 1
aid: 1
of: 1
their: 1
party: 1
i: 1
want: 1
christmas: 1
my: 1
two: 1
front: 1
teeth: 1
a: 1
Total number of lines in file: 4
Total number of unique words in file: 29
Total number of words in file: 44
Longest word: christmas
Shortest word: i
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.