0

Sorry if the title is confusing. I have a program that reads characters from a file and keeps counters of the frequency of each ASCII character. At the end, the program is supposed to output each ASCII character used as well as the number of times (counter) it was used.

Here is my code, which compiles and runs fine (please note that commented out code is just previous code I had used that did not work; I am keeping it in there for my reference):

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

int main(void)
{
    ifstream inputFile;
    string infile;
    char ch;
    int i;
    int asciiArray[128] = {0};

    // Gets input filename from user, checks to make sure it can be opened, and then
    // gets output filename from user.
    cout << "Please enter your input filename: ";
    cin >> infile;

    inputFile.open(infile.c_str());

    if (inputFile.fail())
    {
        cout << "Input file could not be opened. Try again." << endl;
        exit(0);
    }

    // Gets the first character of the input file.
    //inputFile.get(ch);

    // Sets up the ASCII/Frequency table
    cout << left << setw(10) << "ASCII" << right << setw(10) << "Frequency" << endl;

    while(inputFile >> ch)
    {
        asciiArray[(int)ch]++;

        for (i = 0; i < 129; i++)
        {
            if (asciiArray[i] > 0)
            {
                cout << left << setw(10) << asciiArray[i] << right << setw(10) << asciiArray[(int)ch] << endl;
            }
        }
    }

    /*
    while(!inputFile.eof())
    {
        asciiArray[(int)ch]++;
        //cout << asciiArray[(int)ch] << endl;

        for (i = 0; i < 129; i++)
        {
            if (asciiArray[i] > 0)
            {
                cout << left << setw(10) << asciiArray[i] << right << setw(10) << asciiArray[(int)ch] << endl;
            }
        }

        inputFile.get(ch);
    }
    */

    // Closes the input file
    inputFile.close();

    return 0;
}

When running the program with a file containing:

111
[newline added by text editor]

I get the following output: http://puu.sh/7jbnl.png

I'm a bit lost and am not sure where those random long numbers are coming from. I have a feeling perhaps I've put my for loop in the wrong place, as I tend to get mixed up when it comes to loops. But otherwise, I'm pretty stuck.

Note: I asked a question regarding this program earlier today (C++: Counting the frequency of ASCII characters in file), but it was regarding implementing the counter itself (which I believe I've figured out).

Community
  • 1
  • 1
korina
  • 39
  • 3
  • 9
  • Why do you have your summarized output code *inside* the input processing loop? What do you expect that to do other than spew output all over the place? – dmckee --- ex-moderator kitten Mar 04 '14 at 22:54
  • Your first debugging tool is going through the program as if it were a list of instruction to you and seeing what you've told yourself to do. The second debugging tool is using the debugger to check that you have understood the instructions correctly. – dmckee --- ex-moderator kitten Mar 04 '14 at 22:58

2 Answers2

1

Your loop boundary is wrong.

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

should be:

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

You're accessing asciiArray[128], which is outside the array bounds, resulting in undefined behavior. It's reading some unrelated memory that you didn't initialize to 0.

You should also move that loop to after you finish reading the file. You're printing all the frequencies after each character is read.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

The way you print is wrong. You want to print after counting all of ASCII chars. Since you print during each iteration.

Restructuring the loop to:

while(inputFile >> ch)
{
    asciiArray[(int)ch]++;
}

for (i = 0; i < 128; i++)
{
  if (asciiArray[i] > 0)
  {
    cout << left << setw(10) << i << right << setw(10) << asciiArray[i] << endl;
  }
}

would solve the problem. Note that I have changed the loop condition to i<128 as there can be only 128 elements in the array (indexes from 0 to 127).

P.P
  • 117,907
  • 20
  • 175
  • 238
  • Thank you so much! I guess I overlooked the loop boundary. :) I also noticed that you changed `asciiArray[i]` to just `i` and `asciArray[(int)ch]` to `asciiArray[i]`, which cleared up a LOT of confusion regarding why the numbers were wrong. I added your suggested fixes and it looks like the programming is functioning properly now. – korina Mar 04 '14 at 23:13