An array of chars

Pages: 123
closed account (23q2T05o)
hiii soo

hi, so the user has to input a sentence that ends with '#'.
So i have to output how many words we have in the sentence, i gotta split the words from the sentence /if my sentence is like this: "Hi guys#", the output has to be in alphabetical order: guys, hi/

so this is what i have written so far:

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
#include <iostream>
using namespace std;

const int MAX = 1000;
const int MAX_SIZE_OF_A_NAME = 64;


int main() {
	char names[MAX];
	size_t size = strlen(names);
	int counter = 0;

	char** names2;
	names2 = new(nothrow)char* [MAX_SIZE_OF_A_NAME];

	cin.getline(names, MAX);
	for (size_t i = 0; i < size; i++)
	{
		if (names[i] == ' ' || names[i] == '#')
			counter++;
	}

	for (size_t i = 0; i < counter; i++)
	{
			names2[i] = new(nothrow)char[size + 1];
			
			strcpy(names2[i], names);
			cout << names2[i] << ' ' << endl;
	}
	cout << "total words: " << counter << endl;

	//i will a sorting method
	cout << "the words sorted looks like this: ";
	for (size_t i = 0; i < counter; i++)
	{
		cout << i << ":";
		cout << names2[i] << endl;
	}

	for (size_t i = 0; i < size; i++)
	{
		delete[]names2[i];
	}
	delete[]names2;


	return 0;
}


the problem is idk how to split the words, my func here:
1
2
3
4
5
6
7
for (size_t i = 0; i < counter; i++)
	{
			names2[i] = new(nothrow)char[size + 1];
			
			strcpy(names2[i], names);
			cout << names2[i] << ' ' << endl;
	}


doesnt do the right thing, it just couts the whole sentence, i want everey names2[i] to output every word in the sentence splitted so then i could sort them into alphabetical order and find how many unique words i have and how many of them are repeated, idk what to change in the func above, thaks in advance i am new to c++
Last edited on
closed account (23q2T05o)
but after i have splitted them i want to sort them and find how many unique words and how many repeated words i have?
it just couts the whole sentence, i want everey names2[i] to output every word in the sentence splitted so then i could sort them into alphabetical order and find how many unique words i have and how many of them are repeated

strtok does what you asked for, among many other possibilities.

but after i have splitted them i want to sort them and find how many unique words and how many repeated words i have?

Is that a statement or a question? If it's a question then perhaps try a bubble-sort or similar.
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
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cctype>
#include <map>
using namespace std;

string filter( const string &str )
{
   string result;
   for ( char c : str ) if ( isalnum( c ) || isspace( c ) ) result += tolower( c );
   return result;
}


int main()
{
// ifstream in( "input.txt" );
   istringstream in( "Three blind mice, three blind mice,\n"
                     "See how they run, see how they run,\n"
                     "They all ran after the farmer's wife,\n"
                     "Who cut off their tails with a carving knife,\n"
                     "Did ever you see such a thing in your life,\n"
                     "As three blind mice.\n" );

   map<string,int> words;
   for ( string str; in >> str; )
   {
      str = filter( str );
      if ( str != "" ) words[str]++;
   }

   for ( auto pr : words ) cout << pr.first << '\t' << pr.second << '\n';
}


a	2
after	1
all	1
as	1
blind	3
carving	1
cut	1
did	1
ever	1
farmers	1
how	2
in	1
knife	1
life	1
mice	3
off	1
ran	1
run	2
see	3
such	1
tails	1
the	1
their	1
they	3
thing	1
three	3
who	1
wife	1
with	1
you	1
your	1

The nice thing with strtok is that you don't need a second copy of the words.

I see several problems with your current code. I'll describe them first and then give some code to parse the file with strtok.
Line 10: names is uninitialized, so size will be some random number.
Line 14: You allocate space for only 64 words.
Line 16: You read just one line. Can the infile look like this:?
This is a test
That's one small step for a man
One giant leap for mankind.#

Line 19. If there are two spaces together then it will think there are two words.
Line 25: you're allocating too much space for each word. I suggest that you change "name" and "name2" to "buffer" and "words" to keep to it clear which is which. Then change MAX and MAX_SIZE_OF_A_NAME to MAX_BUFFER_SIZE and MAX_WORD_SIZE. Although as you'll see below, you won't need MAX_WORD_SIZE if you use strtok
Line 27: You're copying the entire buffer into each word.

So here is some code that will read the file and parse out the words. Read the links on how strtok() works. make sure you understand this code and then add code at the end to sort the words and print them out in sorted order.

Once you have the words sorted, it's pretty easy to count the number of occurences of each.
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
#include <iostream>
#include <cstring>
using namespace std;

const int MAX_BUFFER_SIZE = 1000;
const int MAX_WORDS = MAX_BUFFER_SIZE/4;

char buffer[MAX_BUFFER_SIZE];	// holds the whole input buffer
char *words[MAX_WORDS];		// points to words within the buffer

int main() {
    cin.getline(buffer, MAX_BUFFER_SIZE, '#'); // http://www.cplusplus.com/reference/istream/istream/getline/

    // Parse out the words.
    // http://www.cplusplus.com/reference/cstring/strtok/
    unsigned numWords = 0;
    for (char *cp = strtok(buffer, " \t\n#"); cp; cp = strtok(nullptr, " \t\n#")) {
	words[numWords++] = cp;
    }

    cout << "total words: " << numWords << endl;

    // Print the (unsorted) words
    for (size_t i = 0; i < numWords; ++i) {
	cout << words[i] << '\n';
    }
}

are you still unable or unwilling to use strtok? Its getting difficult to follow.
you started out saying no string.h and your posted code has strcpy, you followed that with no strtok, but everything posted talks about it... where we at today?
I already showed an example of strtok and a rough example that avoids strtok.

Basically, if it's not clear, you need to transform "hello world" into "hello\0world", and collect char pointers to both the h and the w.
Then, you can use those pointers and sort them based on str comparison functions.
Oops
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
#include <iostream>
#include <fstream>
const int MAX_WORD_SIZE{20};
const int MAX_LIST_SIZE{1000};
void lcase( const char*, char*);
void sort(int, char (*)[MAX_WORD_SIZE], int*);
int main()
{
    char word[MAX_WORD_SIZE];
    char raw_list[MAX_LIST_SIZE][MAX_WORD_SIZE];
    int  word_count[MAX_LIST_SIZE]{0};
    char unique_list[MAX_LIST_SIZE][MAX_WORD_SIZE];
    std::ifstream fin ("three_mice.txt");
    if (!fin.is_open()){
        std::cout << "Unable to open file";
        exit(1);
    }
    size_t last_pos{0};
    int COUNT{0};
    while ( COUNT < MAX_LIST_SIZE and fin >> word ){
        last_pos = strlen(word) - 1;
        if( !isalnum( word[last_pos]) ){
            word[last_pos] = '\0';
        }
        strcpy(raw_list[COUNT], word);
        COUNT++;
    }
    fin.close();
    std::cout << "*** FORWARD LIST OF ALL WORDS ***\n";
    for(int i = 0; i < COUNT; ++i){
        std::cout << i << '\t' << raw_list[i] << '\n';
    }
    std::cout << "\n\n";
    
    std::cout << "*** REVERSE LIST OF ALL WORDS ***\n";
    for(int i = COUNT; i > 0; i--){
        std::cout << i - 1 << '\t' << raw_list[i-1] << '\n';
    }
    std::cout << "\n\n";
    
    int UNIQUE_COUNT{0};
    bool found = false;
    char temp[MAX_WORD_SIZE];
    for(int i = 0; i < COUNT; ++i){
        lcase(raw_list[i], temp);
        found = false;
        for(int j = 0; j < UNIQUE_COUNT; ++j){
            if( strcmp(unique_list[j], temp) == 0 ){
                word_count[j]++;
                found = true;
            }
        }
        if (found == false){
            strcpy(unique_list[UNIQUE_COUNT], temp);
            word_count[UNIQUE_COUNT]++;
            UNIQUE_COUNT++;
        }
    }
    sort( UNIQUE_COUNT, unique_list, word_count);
    std::cout << "SORTED WORD + FREQUENCY\n";
    for(int i = 0; i < UNIQUE_COUNT; i++){
        std::cout
        << i << ' ' << word_count[i] << ' '
        << unique_list[i] << '\n';
    }
    std::cout << '\n';
    return 0;
}

void lcase( const char* src, char* dest){
    int i{0};
    while(src[i] != '\0')
    {
        dest[i] = tolower(src[i]);
        i++;
    }
    dest[i] = '\0';
}
void sort(int count, char (*aList)[MAX_WORD_SIZE], int* aWordCount){
    char temp[MAX_WORD_SIZE];
    int tmp{0};
    for(int i = 1; i <= count; i++){
        for(int j = 0; j < count - i; j++){
            if( strcmp(aList[j], aList[j + 1]) > 0){
                strcpy(temp, aList[j]);
                strcpy(aList[j], aList[j + 1]);
                strcpy(aList[j + 1],temp);
                
                tmp = aWordCount[j];
                aWordCount[j] = aWordCount[j + 1];
                aWordCount[j + 1] = tmp;
            }
        }
    }
}


SORTED WORD + FREQUENCY
0 2 a
1 1 after
2 1 all
3 1 as
4 3 blind
5 1 carving
6 1 cut
7 1 did
8 1 ever
9 1 farmer's
10 2 how
11 1 in
12 1 knife
13 1 life
14 3 mice
15 1 off
16 1 ran
17 2 run
18 3 see
19 1 such
20 1 tails
21 1 the
22 1 their
23 3 they
24 1 thing
25 3 three
26 1 who
27 1 wife
28 1 with
29 1 you
30 1 your
Last edited on
It's goo goo againtry!
Move out of mommy's basement, loser!
Topic archived. No new replies allowed.
Pages: 123