How to make a dynamic array in my code using C-String pointers.

Hello all! I am working on an assignment but have run into some issues, on the very last day its due of course :( I was wondering if I could have someone take a look at my code and tell me how I can turn my data into a dynamic array and utilize the rest of the functions I wrote. Any help would be appreciated, thank you so much!

Here is the directions:

Write a function that accepts a pointer to a C-string as an argument and calculates the number of words contained in the string as well as the number of letters in the string. Communicate both of these values back to the main function, but DO NOT use global variables.

Write another function that accepts the number of letters and the number of words and sends the average number of letters per word (or average word size) back to the main function.

Demonstrate the functions in a program that asks the user to input a string. First, store the input in a large array. The program should dynamically allocate just enough memory to store the contents of that array. Copy the contents of the large array into the dynamically allocated memory. Then the program should pass that new, dynamically allocated array to the first function. Both the number of words and the average word size should be displayed on the screen. Round the average word size to 2 decimal places.

For instance, if the string argument is "Four score and seven years ago" the first function (word count) should calculate and send back a word count of 6 and a letter count of 25. The second function (average word size) should send back 4.17, or 25 / 6.

Extra challenge: See if you can prevent the program from counting punctuation (such as quotes or periods) as part of the sentence. Also, see if you can prevent the program from counting extra spaces as new words. For instance, 2 spaces will often follow a colon, such as the sentence: "There are 3 primary colors: red, blue, and green." In this example, the word count should be 9 (the number 3 does count as a 1-letter word), and the letter count should be 37, for an average of 4.11.

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
#include <iostream>
#include <cstring>
#include <iomanip>

using namespace std;

void Count_All(char*, int&, double&, int&); // Function prototype.
double Calc_Average (char*, int, int, double); // Function prototype.

int main()
{
    const int size = 500;
    char userString[size];
    int Word = 0;
    int Pun = 0;
    double Total_Characters = 0;
    double Average = 0.0;
    
    cout << "Please enter a string of 500 or less characters: ";
    cin.getline(userString, size);
    cout << "\n";
    
    Count_All (userString, Word, Total_Characters, Pun);
    cout << "Number of words in the string: " << Word << "\n";
    Average = Calc_Average (userString, Word, Pun, Total_Characters);
    cout <<"\nAverage number of letters per word: "<< fixed <<
    showpoint << setprecision(2) << Average << "\n" << endl;
    
    
    cin.ignore(1);
    return 0;
}

void Count_All (char*strptr, int &Word, double &Total_Characters, int &Pun) // Counts all characters and types.
{
    int index = 0;
    
    while (*strptr != '\0')
    {
        if ((isspace(*strptr)) || (ispunct(*strptr)))
        {
            while ((isspace(*strptr)) || (ispunct(*strptr)))
            {
                index++;
            }
        }
        
        if ((isalnum(*strptr)) || (ispunct(*strptr)))
        {
            Word++;
            while ((isalnum(*strptr))||(ispunct(*strptr)))
            {
                index++;
                Total_Characters++; // Counting the total printable characters (including digits and punctuation).
                
                if((ispunct(*strptr)))
                {
                    Pun++; // Counting punctuation.
                }
                
            }
        }
        index++;
    }
}

double Calc_Average(char*strptr, int Word, int Pun, double Total_Characters)  // Calculates the average number of characters per words.
{
    double Average = 0.0;
    Total_Characters = Total_Characters - Pun; // Subtracting punctuation from all of the characters in the string (not including spaces).
    Average = (Total_Characters / Word);
    return Average;
}
You declare a dynamic array like this:
1
2
3
4
5
6
7
8
9
10
cin.getline(userString, size);
int len = strlen(userString);
char *dyn_array = new char[len+1];
strcpy(dyn_array, userString);
Count_All (dyn_array, Word, Total_Characters, Pun);
...
Average = Calc_Average (dyn_array, Word, Pun, Total_Characters);
....
delete [] dyn_array;
return0;


BTW. Your code is clearly structured and readable. Congrats.
I will make adjustments and get back to you! Also, is that last statement actually true or sarcastic? :D
Thomas1965, I made your adjustments and it works just fine :)

One question though, I am using XCode on a Mac and for

 
int len = strlen(userString);


I get an error saying "Implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int'"

Any idea of a workaround? Thank you!
Any idea of a workaround? Thank you!

Yes, use a size_t instead of an int.
Also, is that last statement actually true or sarcastic? :D

It's absolutely true.
Since when does strlen return a size_t ?
What is a size_t? Can i just throw an unsigned in front of the int? Will that work?

Also, any idea of how I can count the letters from the input string, which would exclude the spaces and punctuation? I would imagine it would look similar to my Count_All function but I am not sure what would need to be incremented and such.
Can i just throw an unsigned in front of the int?

Not really. While it may work under some circumstances, it will fail under many others.

Will that work?

Using the correct type for the job, in this case a size_t is the correct type.

What is a size_t?

It is an implementation defined unsigned type. It is used when you need a variable that can hold the size of any object in memory.

By the way what line is causing the warning?

Also, any idea of how I can count the letters from the input string,

Yes it should be similar to your Count_all() function.
So I added an if statement to count letters in my function but it seems it isn't working properly. When I entered "Why hello there!" (minus the parentheses in that string) it displayed the number of letters as three, number of words as three, and average letters per word as 4.33. The number of letters should be 13. Any idea what could be wrong? Here is my current code:

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
#include <iostream>
#include <cstring>
#include <iomanip>

using namespace std;

void Count_All(char*, int&, int&, double&, int&); // Function prototype.
double Calc_Average (char*, int, int, double); // Function prototype.

int main()
{
    const int size = 500;
    char userString[size];
    int Word = 0;
    int Pun = 0;
    int Letters = 0;
    double Total_Characters = 0;
    double Average = 0.0;
    
    cout << "Please enter a string of 500 or less characters: ";
    cin.getline(userString, size);
    
    int len = strlen(userString);
    char *Dyn_Array = new char[len+1];
    strcpy(Dyn_Array, userString);
    
    cout << "\n";
    
    Count_All (Dyn_Array, Letters, Word, Total_Characters, Pun);
    
    cout << "Number of letters in the string: " << Letters << "\n";
    cout << "\n";
    cout << "Number of words in the string: " << Word << "\n";
    cout << "\n";
    
    Average = Calc_Average (Dyn_Array, Word, Pun, Total_Characters);
    cout <<"Average number of letters per word: "<< fixed <<
    showpoint << setprecision(2) << Average << "\n" << endl;
    
    
    cin.ignore(1);
    delete [] Dyn_Array;
    return 0;
}

void Count_All (char*strptr, int &Letters, int &Word, double &Total_Characters, int &Pun) // Counts all characters and types.
{
    while (*strptr != '\0')
    {
        if ((isspace(*strptr)) || (ispunct(*strptr)))
        {
            while ((isspace(*strptr)) || (ispunct(*strptr)))
            {
                strptr++;
            }
        }
        
        if (((*strptr >= 'a') && (*strptr <= 'z')) || ((*strptr >= 'A') && (*strptr <= 'Z')))
            Letters++;
        
        if ((isalnum(*strptr)) || (ispunct(*strptr)))
        {
            Word++;
            while ((isalnum(*strptr))||(ispunct(*strptr)))
            {
                strptr++;
                Total_Characters++; // Counting the total printable characters (including digits and punctuation).
                
                if((ispunct(*strptr)))
                {
                    Pun++; // Counting punctuation.
                }
                
            }
        }
        strptr++;
    }
}

double Calc_Average(char*strptr, int Word, int Pun, double Total_Characters)  // Calculates the average number of characters per words.
{
    double Average = 0.0;
    Total_Characters = Total_Characters - Pun; // Subtracting punctuation from all of the characters in the string (not including spaces).
    Average = (Total_Characters / Word);
    return Average;
}
I think you need to rethink your count all function. It appears to me that you're incrementing strptr in too many places. You probably don't need multiple while statements in this function, one should do nicely. You really should only be incrementing the pointer in one place.

Is there any way I can directly message you jib? I am lost if I have to rework everything, I wouldn't know where to begin or anything :(
Start with a single loop and add an if() statement to count only the alpha characters. Then once you have that correct add another if() statement to count only the punctuation characters, etc. You should only need one loop, that contains an if statement that checks for each of the desired type of characters.

Is there any way I can directly message you jib?

It probably wouldn't do you any good because I normally don't answer PMs.

Last edited on
Topic archived. No new replies allowed.