selection sort of char array

I have a code that reads in data from a file and outputs the frequency of each letter in the file. It counts the number of words in the file and the total number of letters in the file. I need to be able to display the array of words in alphabetical order, using selection sort and ignoring punctuation. I've been working on it and cannot figure out how to do this. If someone could please help me with this?
my input file reads:
this is a test file
to read from, for this assignment.
is this the third line?
should i miss this!!!?

Here's what I have currently:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  #include<iostream>
#include<iomanip>
#include<fstream>
#include<string>

using namespace std;
const int MAX = 1000;
void printFreq(char ch, int array[], ofstream& outfile);
void sort(char array[], int size);
void printSort(ofstream& outfile, char word[], int size);

int main()
{
	ifstream infile;
	ofstream outfile;
	string freqWord;
	int letters[MAX];
	int words = 0, letts = 0, maxfreq = 0, difwords = 0;
	char ch, word[MAX];
	infile.open("mp6infile.txt");
	outfile.open("outputt.txt");

	outfile << left << setw(12) << "Letter" << setw(12) << "Count" << "Frequency" << endl;
	outfile << setw(12) << "======" << setw(12) << "=====" << "=========" << endl;

	for (int i = 0; i <= MAX; i++)
	{
		letters[i] = 0;
	}

	while (!infile.eof())
	{
		infile >> word;
		words++;
		for (int i = 0; word[i] != '\0'; i++)
		{
			ch = word[i];
			ch = toupper(ch);
			if (isalpha(ch))
			{
				letts++;
			}
			letters[ch]++;
			if (maxfreq < letters[ch])
			{
				maxfreq = letters[ch];
			}
		}
	
	}
	
	printFreq(ch, letters, outfile);
	outfile << endl << "The file has " << words << " words and " << letts << " letters." << endl;
	outfile << "The highest frequency is " << maxfreq << endl << endl;
	outfile << "The file sorted alphabetically:" << endl;
	/*sort(word, words);*/
	printSort(outfile, word, words);
	outfile << endl  << endl << "There are " << difwords << " different words." << endl;
	outfile << "The word that appears most frequently is: " << freqWord << endl;


}


void printFreq(char ch, int array[], ofstream& outfile)
{
	ch = toupper(ch);
	for (ch = 'A'; ch <= 'Z'; ch++)
	{
		if (array[ch] > 0)
			outfile << setfill(' ') << right << setw(4) << ch << " " << setw(11) << array[ch] << setw(9) 
				    << " " << setw(array[ch]) << setfill('*') << "*" << endl;
	}
}

void selectionSort(char array[], int size)
{
	char temp;

	for (int i = 0; i <= size; i++)
	{
		for (int j = i + 1; j <= size; j++)
		{
			if (array[i] > array[j])
			{
				temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}
		}
	}
}

void printSort(ofstream& outfile, char word[], int size)
{

	for (int i = 0; i < size; i++)
	{
		if (i % 10 == 0)
		{
			outfile << endl;
		}
		outfile << word << " ";
	}
}


and I'm getting an output of:
Letter Count Frequency
====== ===== =========
A 3 ***
D 3 ***
E 6 ******
F 3 ***
G 1 *
H 7 *******
I 12 ************
L 3 ***
M 3 ***
N 3 ***
O 4 ****
R 4 ****
S 12 ************
T 10 **********
U 1 *

The file has 20 words and 75 letters.
The highest frequency is 12

The file sorted alphabetically:

this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!?
this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!? this!!!?

There are 0 different words.
The word that appears most frequently is:
Hello mdelellis,

You write:
I need to be able to display the array of words in alphabetical order
, but you do not have an array of words just a "char" array for a single word, which would be better as a "std::string".

Do want to sort an array of words or sort the letters in a single word? If yo want to sort words yo will have to rearrange the program to store an array of words, although I would suggest a vector over an array.

For now the program appears to be doing what it should do. Although it seems to be cutting off the "T" when it is the first letter of a sentence. Not sure why yet.

Hope that helps,

Andy
Most of the initial post and logic is working; very nice!

Rewrote for stringstream:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

void printFreq(const vector<int>& letters, int& maxfreq, ostringstream& oss)
{
    // Header
    oss << left << setw(12) << "Letter" << setw(12) << "Count" << "Frequency" << endl;
    oss << setw(12) << "======" << setw(12) << "=====" << "=========" << endl;
    
    int count;
    int max = -1;
    for (char ch = 'A'; ch <= 'Z'; ch++)
    {
        count = letters[ch-'A'];  // Offset of 65
        if (count > 0)
        {
            oss << setfill(' ') << right << setw(4) << ch << " " << 
                   setw(11) << count << setw(9) << " " << 
                   setw(count) << setfill('*') << "*" << endl;
            if (count > max)
                max = count;
        }
    }
    maxfreq = max;
}

void selectionSort(vector<string>& array)
{
    for (int i = 0; i < array.size(); i++)
    {
        string& iword = array[i];
        for (int j = i + 1; j < array.size(); j++)
        {
            string& jword = array[j];
            
            // Sorts by first character -- could be improved
            if (toupper(iword[0]) > toupper(jword[0]) )
            {
                swap(iword, jword);
            }
        }
    }
}

void printWrapped(ostringstream& oss, const vector<string>& words)
{

    for (int i = 0; i < words.size(); i++)
    {
        if (i % 10 == 0)
        {
            oss << endl;
        }
        oss << words[i] << " ";
    }
    oss << endl;
}

int main()
{
    const char* data_text = R"LITERAL(
this is a test file
to read from, for this assignment.
is this the third line?
should i miss this!!!?
)LITERAL";

    // Imitate file streams
    istringstream iss(data_text);
    ostringstream oss;

    string freqWord("");
    vector<int> letters(26, 0);
    int letts = 0, maxfreq = 0, difwords = 0;
    char ch;
    string word;
    vector<string> all_words;

    for ( ; iss>>word; )
    {
        all_words.emplace_back(word);
        for (int i = 0; word[i] != '\0'; i++)
        {
            ch = word[i];
            if (isalpha(ch))
            {
                letts++;
                ch = toupper(ch);
                letters[ch-'A']++;
            }
        }
    }
    
    printFreq(letters, maxfreq, oss);
    oss << endl << "The file has " << all_words.size() << " words and " << letts << " letters." << endl;
    oss << "The highest frequency is " << maxfreq << endl << endl;
    oss << "The file, word-wrapped, before sorting:" << endl;
    printWrapped(oss, all_words);
    oss << endl;
    oss << "The file, word-wrapped, sorted alphabetically by first character:" << endl;
    selectionSort(all_words);
    printWrapped(oss, all_words);
    oss << endl  << endl << "There are " << difwords << " different words." << endl;
    oss << "The word that appears most frequently is: " << freqWord << endl;

    // Shows the stream as a string
    cout << oss.str();
    
    return 0;
}


Running at https://repl.it/repls/OrderlySandybrownProtocols

Letter      Count       Frequency
======      =====       =========
   A           3         ***
   D           3         ***
   E           6         ******
   F           3         ***
   G           1         *
   H           7         *******
   I          12         ************
   L           3         ***
   M           3         ***
   N           3         ***
   O           4         ****
   R           4         ****
   S          12         ************
   T          10         **********
   U           1         *

The file has 20 words and 75 letters.
The highest frequency is 12

The file, word-wrapped, before sorting:

this is a test file to read from, for this 
assignment. is this the third line? should i miss this!!!? 

The file, word-wrapped, sorted alphabetically by first character:

a assignment. from, for file is is i line? miss 
read should this the third to this test this this!!!? 


There are 0 different words.
The word that appears most frequently is: 


Changes:
- used stringstream instead of fstream for example purposes (they work very similarly)
- rearranged methods so that declaration can be avoided ;D
- previously letters was an array of size 1000, but now it's a vector of size 26, since you're ignoring other characters anyway.
- to avoid wrong indices, the logic for inserting things into letters is moved under the isalpha condition check
- moved header and maxfreq calculation to printFreq() method
- a word is a std::string, and words are stored in vector<string> just as Handy Andy suggested. The words are added by calling emplace_back or push_back vector methods.
- printWrapped(), renamed because it can print the words whether they've been sorted or not
- selectionSort() -- you had some off-by-one indexing errors in your loops. Refactored to make use of the new words vector.
- selectionSort() -- swaps can be made using std::swap instead of temporary variables, as long as we have references. You can do without creation of iword and jword, but these may prove useful when you improve the method.
- selectionSort() currently sorts based on the first character of a word. You can improve to sort on the whole word.
- different words -- this is another feature you still need to add

good luck

Topic archived. No new replies allowed.