Struct and Void functions

Pages: 12
I am trying to write a program that takes wind speed from an input file and convert it to the category of hurricane.
The text file has other info and I think I have got most of my code working. I just can figure out how to 'categorize' the hurricanes based on the wind speed, if that makes sense? A struct is required for the assignment.


Reference:

Wind Speed (MPH)   Category
<74                Tropical Storm
74 - 95            Category 1
96 - 110           Category 2
111 - 130          Category 3
131 - 155          Category 4
>155               Category 5


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

// Constant variable
    const int MONTHS_OF_YEAR = 12;

// Create struct
    struct hurricane
    {
        string month;
        string name;
        int year;
        int windSpeed;
    };

// Function Prototypes
    void categorize(hurricane hList[], int listSize);

// Function to categorize storms
void categorize(hurricane hList[], int listSize) //<--- here I am not sure that a void is going to work
{
    // string cat = categorize(hList, listSize); <--- I think this needs to be in the output function printResults?? I know that this line is all wrong. 

    for (int i = 0; i < listSize; i++)
    {
        if (hList[i].windSpeed < 74)
        {
            cout << "Tropical Storm";
        }
        else if (hList[i].windSpeed >= 74 && hList[i].windSpeed <= 95)
        {
            cout << "Category 1";
        }
        else if (hList[i].windSpeed >= 96 && hList[i].windSpeed <= 110)
        {
            cout << "Category 2";
        }
        else if (hList[i].windSpeed >= 111 && hList[i].windSpeed <= 130)
        {
            cout << "Category 3";
        }
        else if (hList[i].windSpeed >= 131 && hList[i].windSpeed <= 155)
        {
            cout << "Category 4";
        }
        else
            cout << "Category 5";
    }
    // return cat; <--- here is the 'info' I need in the output "classification", I know voids do not return anything
}



Expected Output:

Month     Name   Year  Max Winds(mph)  Classification
=====     ====   ====  ==============  ==============
January   Pali   2016       100        Category 2
February  Ekeka  1992       115        Category 3
...
...
December  Omeka  2010        60        Tropical Storm
It appears your question is about categorizing the wind on the basis of the numerical wind speed. That being the case your struct or whatever needs a function/method along the following lines.

You also could have the categories as a static or other permanent array to avoid transferring that around each time.

The principle is, as my function shows - hive me a wind speed and I'll give you a category name in return.

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
#include <iostream>
#include <string>

std::string categorize(int windspeed)
{
    if (windspeed < 74)
        return "Tropical Storm";
    else if (windspeed >= 74 && windspeed <= 95)
        return "Category 1";
    else if (windspeed >= 96 && windspeed <= 110)
        return "Category 2";
    else if (windspeed >= 111 && windspeed <= 130)
        return "Category 3";
    else if (windspeed >= 131 && windspeed <= 155)
        return "Category 4";
    else
        return "Category 5";
}

int main()
{
    int wspd = 78;
    std::cout << categorize(wspd) << '\n';
    return 0;
}
Why not include the 'category' member in the struct itself? That way, you can decide what the category is right at insertion.

If not, @againtry provides the correct solution.
againtry provides the correct solution

Not quite.
The lower comparisons aren't needed since they've been excluded by the previous comparisons.
The 'else's aren't needed, either.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::string categorize(int windspeed)
{
    if (windspeed < 74)
        return "Tropical Storm";
    if (windspeed <= 95)
        return "Category 1";
    if (windspeed <= 110)
        return "Category 2";
    if (windspeed <= 130)
        return "Category 3";
    if (windspeed <= 155)
        return "Category 4";
    return "Category 5";
}

Last edited on
Not quite.

~Not quite

1
2
3
4
5
6
7
int main()
{
    for(int wspd = 0; wspd < 200; wspd ++)
    std::cout << wspd << ' ' <<  categorize(wspd) << '\n';
    
    return 0;
}



0 Tropical Storm
1 Tropical Storm
2 Tropical Storm
3 Tropical Storm
4 Tropical Storm
5 Tropical Storm
6 Tropical Storm
7 Tropical Storm
8 Tropical Storm
9 Tropical Storm
10 Tropical Storm
11 Tropical Storm
12 Tropical Storm
13 Tropical Storm
14 Tropical Storm
15 Tropical Storm
16 Tropical Storm
17 Tropical Storm
18 Tropical Storm
19 Tropical Storm
20 Tropical Storm
21 Tropical Storm
22 Tropical Storm
23 Tropical Storm
24 Tropical Storm
25 Tropical Storm
26 Tropical Storm
27 Tropical Storm
28 Tropical Storm
29 Tropical Storm
30 Tropical Storm
31 Tropical Storm
32 Tropical Storm
33 Tropical Storm
34 Tropical Storm
35 Tropical Storm
36 Tropical Storm
37 Tropical Storm
38 Tropical Storm
39 Tropical Storm
40 Tropical Storm
41 Tropical Storm
42 Tropical Storm
43 Tropical Storm
44 Tropical Storm
45 Tropical Storm
46 Tropical Storm
47 Tropical Storm
48 Tropical Storm
49 Tropical Storm
50 Tropical Storm
51 Tropical Storm
52 Tropical Storm
53 Tropical Storm
54 Tropical Storm
55 Tropical Storm
56 Tropical Storm
57 Tropical Storm
58 Tropical Storm
59 Tropical Storm
60 Tropical Storm
61 Tropical Storm
62 Tropical Storm
63 Tropical Storm
64 Tropical Storm
65 Tropical Storm
66 Tropical Storm
67 Tropical Storm
68 Tropical Storm
69 Tropical Storm
70 Tropical Storm
71 Tropical Storm
72 Tropical Storm
73 Tropical Storm
74 Category 1
75 Category 1
76 Category 1
77 Category 1
78 Category 1
79 Category 1
80 Category 1
81 Category 1
82 Category 1
83 Category 1
84 Category 1
85 Category 1
86 Category 1
87 Category 1
88 Category 1
89 Category 1
90 Category 1
91 Category 1
92 Category 1
93 Category 1
94 Category 1
95 Category 1
96 Category 2
97 Category 2
98 Category 2
99 Category 2
100 Category 2
101 Category 2
102 Category 2
103 Category 2
104 Category 2
105 Category 2
106 Category 2
107 Category 2
108 Category 2
109 Category 2
110 Category 2
111 Category 3
112 Category 3
113 Category 3
114 Category 3
115 Category 3
116 Category 3
117 Category 3
118 Category 3
119 Category 3
120 Category 3
121 Category 3
122 Category 3
123 Category 3
124 Category 3
125 Category 3
126 Category 3
127 Category 3
128 Category 3
129 Category 3
130 Category 3
131 Category 4
132 Category 4
133 Category 4
134 Category 4
135 Category 4
136 Category 4
137 Category 4
138 Category 4
139 Category 4
140 Category 4
141 Category 4
142 Category 4
143 Category 4
144 Category 4
145 Category 4
146 Category 4
147 Category 4
148 Category 4
149 Category 4
150 Category 4
151 Category 4
152 Category 4
153 Category 4
154 Category 4
155 Category 4
156 Category 5
157 Category 5
158 Category 5
159 Category 5
160 Category 5
161 Category 5
162 Category 5
163 Category 5
164 Category 5
165 Category 5
166 Category 5
167 Category 5
168 Category 5
169 Category 5
170 Category 5
171 Category 5
172 Category 5
173 Category 5
174 Category 5
175 Category 5
176 Category 5
177 Category 5
178 Category 5
179 Category 5
180 Category 5
181 Category 5
182 Category 5
183 Category 5
184 Category 5
185 Category 5
186 Category 5
187 Category 5
188 Category 5
189 Category 5
190 Category 5
191 Category 5
192 Category 5
193 Category 5
194 Category 5
195 Category 5
196 Category 5
197 Category 5
198 Category 5
199 Category 5
Program ended with exit code: 0
~Not quite

The functions generate the same output:
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
#include <iostream>
#include <string>

std::string categorize1(int windspeed)
{
    if (windspeed < 74)
        return "Tropical Storm";
    else if (windspeed >= 74 && windspeed <= 95)
        return "Category 1";
    else if (windspeed >= 96 && windspeed <= 110)
        return "Category 2";
    else if (windspeed >= 111 && windspeed <= 130)
        return "Category 3";
    else if (windspeed >= 131 && windspeed <= 155)
        return "Category 4";
    else
        return "Category 5";
}

std::string categorize2(int windspeed)
{
    if (windspeed < 74)
        return "Tropical Storm";
    if (windspeed <= 95)
        return "Category 1";
    if (windspeed <= 110)
        return "Category 2";
    if (windspeed <= 130)
        return "Category 3";
    if (windspeed <= 155)
        return "Category 4";
    return "Category 5";
}

int main()
{
    std:: cout << "Differences:\n";
    for(int wspd = 0; wspd < 200; wspd ++)
	if (categorize1(wspd) != categorize2(wspd)) {
	    std::cout << wspd << categorize1(wspd) << '\t'
		 << categorize2(wspd) << '\n';
	}   
    std::cout << "Done\n";
    return 0;
}

Differences:
Done


Personally, I'd return a const char * instead of a std::string. Let the caller create the string if they need it.
@dhayden_come_lately,

The issue for my
~Not quite
was never whether the two alternatives, mine and @dutch_colorful produce different results. My only interest and concern was whether mine produced appropriate answers which it does.

There, you have drawn a reaction but I haven't told you to fuck off and do something productive by addressing the OP instead of stalking your betters.
> The 'else's aren't needed, either.
excluding the else is a conceptual error
if you already know that it's a cat1 ┬┐why are you testing for cat2 to cat5?

ja, scratch that, was still on the cout version, not the return one
Last edited on
I haven't told you to fuck off and do something productive by addressing the OP instead of stalking your betters.
I see your paper-thin ego is still as fragile as ever.
Do something productive grandpa.
My only interest and concern was whether mine produced appropriate answers which it does.
No one ever suggested it didn't. Dutch just suggested a better way to code it. You're so sensitive that you see any criticism of your code as a personal attack. It isn't. Get over your self and grown the fvck up.
Thank you for all the responses!! I will try today.
This is what I have so far with notes on what is required. So far the program will debug until the "categorize" function.

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

using namespace std;
/// Constant variable
    const int MONTHS_OF_YEAR = 12;

/// Create struct
    struct hurricane
    {
        string month;
        string name;
        int year;
        int windSpeed;
    };

/// Function Prototypes
    void getData(ifstream& inFile, hurricane hList[], int listSize);
    string categorize(int windSpeed);
    void printResults(hurricane hList[], int listSize);

int main()
{
/// Declare Variables
    int wspd = 78;

    ifstream inFile;

/// Build array for input
    hurricane hurricaneList[MONTHS_OF_YEAR];

/// Open input file
    inFile.open("hurricans.txt");
    if (!inFile) //verify file opens
    {
        cout << "Cannot open input file. Program terminates!" << endl;
        return 1;
    }

/// Call functions
    getData(inFile, hurricaneList, MONTHS_OF_YEAR);
    categorize(wspd);
    printResults(hurricaneList, MONTHS_OF_YEAR);

/// Close input file
    inFile.close();

    return 0;
}

/// Function to read input file
void getData(ifstream& inFile, hurricane hList[], int listSize)
{
    for (int i = 0; i < listSize; i++)
    {
        inFile >> hList[i].month >> hList[i].name >> hList[i].year >> hList[i].windSpeed;
    }
}

/// Function to categorize storms   <-----This is what I can't figure out. I must utilize a struct.
string categorize(int windSpeed)
{
    // string cat = categorize(hList, listSize);

    if (hurricane.windspeed < 74)
        return "Tropical Storm";
    else if (hurricane.windspeed >= 74 && hurricane.windspeed <= 95)
        return "Category 1";
    else if (hurricane.windspeed >= 96 && hurricane.windspeed <= 110)
        return "Category 2";
    else if (hurricane.windspeed >= 111 && hurricane.windspeed <= 130)
        return "Category 3";
    else if (hurricane.windspeed >= 131 && hurricane.windspeed <= 155)
        return "Category 4";
    else
        return "Category 5";
    // return cat;
}

/// Function to print table
void printResults(hurricane hList[], int listSize)
{
    for (int i = 0; i < listSize; i++)
    {
        cout << left << setw(15) << hList[i].month
             << left << setw(10) << hList[i].name
             << right << setw(10) << hList[i].year
             << right << setw(10) << hList[i].windSpeed
             << left << setw(15) << cat << endl;
    }
}
In your categorize function it is windSpeed, not hurricane.windSpeed within the function which takes an int parameter.

That parameter you pass to the categorize function, as an int, can of course be hurricane.windSpeed

e.g.

hurricane h( ... etc);
std::cout << categorize(h.windSpeed);

etc
Last edited on
Hello Fayezilla,

I would say that you are about 98% of what you need.

It would help if you would provide the input file so evaey one can use the same information with out having to guess at it.

"MONTHS_OF_YEAR" works, but "MONTHS_IN_YEAR" sounds better. Not saying that you have to change it, but just consider it.

Between the prototypes, function definitions and function calls the use of "MONTHS_OF_YEAR" is not necessary as it is a global variable with file scope and all you have to do is use it.

In "main" you define int wspd = 78; which has no real use. Then later you call categorize(wspd);, but this is in the wrong place and the value of "wspd" has no meaning.

The function "getData" should work, but I have nothing to test it with. The for loop should look more like this: for (int i = 0; i < MONTHS_OF_YEAR; i++). Since this is a global variable that all you have to do is use.

In the "categorize" function either send the function a complete struct from the array or just the wind speed as you have. If you sent the function an int then the if statements would need to be changed to use "windSpeed" on the lhs of the compares.

The "print" function is missing the 2 lines for the heading. In the for loop the default is "right", so when you start with "left" you do not need it for the second line. "left" will be in effect until it is changed to "right" then "right" will be in effect until it is changed.

In the last line of the "cout" "cat" is not defined in the function before it is used, but what you should be using is: << setw(15) << categorize(hList[i].windSpeed) << endl;. The returned value of the function is the string that you need to print.

In you OP you start with what you call "Reference:". A more accurate version would be:

Reference:

Wind Speed (MPH)   Category
< 38		   Tropical depression
39 - 73            Tropical Storm
74 - 95            Category 1
96 - 110           Category 2
111 - 129          Category 3
130 - 156          Category 4
> 156              Category 5

https://en.wikipedia.org/wiki/Tropical_cyclone_scales#Atlantic,_Eastern_and_Central_Pacific


The link is where I found this.

And I used this for the "categorize" function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (windSpeed < 39)
    catagory = "Tropical depression";
else if (windSpeed > 38 && windSpeed < 74)
    catagory = "Tropical Storm";
else if (windSpeed > 73 && windSpeed < 96)
    catagory = "Category 1";
else if (windSpeed > 95 && windSpeed < 111)
    catagory = "Category 2";
else if (windSpeed > 110 && windSpeed < 130)
    catagory = "Category 3";
else if (windSpeed > 130 && windSpeed < 157)
    catagory = "Category 4";
else
    catagory = "Category 5";

I was playing with something different, so you would need to change "catagory =" to "return".

The "<=" and ">=" have their use, but be careful with how often you use them. Once you get use to them the next thing you know you stick in in a for loop condition then wonder why the for loop is not working right, i.e., doing one more loop than you want or need. Just something to keep in mind.

It will take a while to write a useful input file to test the progeam, but the changes mentioned should work.

Andy
Handy Andy,
thank you, would you mind if I messaged you? also I have no idea how to include an input file here.
Last edited on
Hello Fayezilla,

No I do not mind, but I may not see the message until tomorrow morning.

You can either copy and paste or put in output tags as you did in the first post.

Andy
Input text. Assignment is due tonight. I will still get some points if I submit incomplete. I would still like to solve the problem anyway.


January		Pali		2016	100
February	Ekeka 		1992	115
March		Hali 		1992	50
April		Carmen 		1980	50
May		Amanda		2014	155
June		Ava		1973	160
July		Gilma		1994	160
August		Ioke		2006	160
September	Linda		1997	185
October		Patricia	2015	215
November	Sandra		2015	150
December	Omeka		2010	60
Last edited on
Hello Fayezilla,

That worked and produced the output of:


 Month       Name      Year    Max Winds(mph)    Classification
========    =======    ====    ==============  ===================
January        Pali            2016       100     Category 2
February       Ekeka           1992       115     Category 3
March          Hali            1992        50 Tropical Storm
April          Carmen          1980        50 Tropical Storm
May            Amanda          2014       155     Category 4
June           Ava             1973       160     Category 5
July           Gilma           1994       160     Category 5
August         Ioke            2006       160     Category 5
September      Linda           1997       185     Category 5
October        Patricia        2015       215     Category 5
November       Sandra          2015       150     Category 4
December       Omeka           2010        60 Tropical Storm


With the changes I mentioned.

The spacing needs some work and if it helps this is what I used:
1
2
3
4
5
6
7
8
9
10
11
12
13
std::cout <<
    " Month       Name      Year    Max Winds(mph)    Classification\n"
    "========    =======    ====    ==============  ===================\n";

for (int i = 0; i < MONTHS_OF_YEAR; i++)
{
    std::cout << std::left
        << std::setw(12) << hList.month
        << std::setw(11) << hList.name
        << std::setw(13) << hList.year
        <<std::right << std::setw(3)<<hList.windSpeed
        << std::setw(8) << ' ' << catagory << '\n';
}

I could have done line 12 a little differently, but I did not spend a lot of time on it.

Andy
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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

struct Hurricane
{
    string month;
    string name;
    int year;
    int windSpeed;
    
    string category()
    {
        if (windSpeed < 74)
            return "Tropical Storm";
        else if (windSpeed >= 74 && windSpeed <= 95)
            return "Category 1";
        else if (windSpeed >= 96 && windSpeed <= 110)
            return "Category 2";
        else if (windSpeed >= 111 && windSpeed <= 130)
            return "Category 3";
        else if (windSpeed >= 131 && windSpeed <= 155)
            return "Category 4";
        else
            return "Category 5";
    }
    
    void printResult()
    {
        cout
        << left << setw(15) << month
        << left << setw(10) << name
        << right << setw(10) << year
        << right << setw(10) << windSpeed
        << right << setw(20) << this->category() << endl;
    }
};

int main()
{
    const int MAX_NO_OF_HURRICANES{100};
    Hurricane hurricaneList[MAX_NO_OF_HURRICANES];
    
    ifstream myfile ("hurricane.txt");
    
    Hurricane temp;
    int count{0};
    
    if (myfile.is_open())
    {
        while( myfile
              >> temp.month >> temp.name
              >> temp.year >>temp.windSpeed
              )
        {
            h_list[count] = temp;
                temp.printResult();
                count++; // <--- OOPS!
        }
        
        myfile.close();
    }
    
    
    for(int i = 0; i < count; i++)
    hurricaneList[i].printResult();
    
    return 0;
}


January        Pali            2016       100          Category 2
February       Ekeka           1992       115          Category 3
March          Hali            1992        50      Tropical Storm
April          Carmen          1980        50      Tropical Storm
May            Amanda          2014       155          Category 4
June           Ava             1973       160          Category 5
July           Gilma           1994       160          Category 5
August         Ioke            2006       160          Category 5
September      Linda           1997       185          Category 5
October        Patricia        2015       215          Category 5
November       Sandra          2015       150          Category 4
December       Omeka           2010        60      Tropical Storm
Program ended with exit code: 0
Last edited on
Pages: 12