Classes...segmentation fault printing

I am so confused....why is there a segmentation fault printing out after the entire program runs? Did I do something wrong with using memory?

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*
	File: month.cpp 
	Description:
	Created: November 13, 2014
*/
#include <iostream>
#include <string>
#include <locale>

using namespace std;

class Month
{
public:
    Month();
    // Default constructor
    void enter_int(int& month);
    void enter_char(char& month_1, char& month_2, char& month_3);
    void assign1(int month);
    void assign2(char month_1, char month_2, char month_3);
    void output(ostream& outs);
    Month next_month(ostream& outs);
    void check_next_mo();
private:
    string month1, new_month1;
    int month_int, new_month_int;
    void check1(int& month);
    void check2(char& month_1, char& month_2, char& month_3);
};

int main( )
{
	Month variable;
    int month;
    char month1, month2, month3;
    variable.enter_int(month);
    variable.enter_char(month1, month2, month3);
    variable.assign1(month);
    variable.assign2(month1, month2, month3);
    variable.output(cout);
    variable.next_month(cout);
    return 0;
}

Month::Month()
{
//    month2 = 1;
}

void Month::enter_int(int& month)
{
    cout << "Enter a number 1-12 for the months: ";
    cin >> month;
    check1(month);
}

void Month::check1(int& month)
{
    while (month <= 0 || month > 12)
    {
        cout << "Invalid input, please enter a number 1-12 for the months: ";
        cin >> month;
    }
}

void Month::enter_char(char& month_1, char& month_2, char& month_3)
{
    cout << "Enter the first 3 characters of the month: ";
    cin >> month_1 >> month_2 >> month_3;
    month_1 = toupper(month_1);
    month_2 = tolower(month_2);
    month_3 = tolower(month_3);
    check2(month_1, month_2, month_3);
}

void Month::check2(char& month_1, char& month_2, char& month_3)
{
    while (month_1 != 'J' && month_1 != 'F' && month_1 != 'M' && month_1 != 'A' && month_1 != 'S' && month_1 != 'O' && month_1 != 'N' && month_1 != 'D')
    {
        cout << "Invalid input, reenter the first 3 characters of the month: ";
        cin >> month_1 >> month_2 >> month_3;
        month_1 = toupper(month_1);
        month_2 = tolower(month_2);
        month_3 = tolower(month_3);
    }
    while (month_2 != 'a' && month_2 != 'e' && month_2 != 'p' && month_2 != 'u' && month_2 != 'c' && month_2 != 'o')
    {
        cout << "Invalid input, reenter the first 3 characters of the month: ";
        cin >> month_1 >> month_2 >> month_3;
        month_1 = toupper(month_1);
        month_2 = tolower(month_2);
        month_3 = tolower(month_3);
    } 
    while (month_3 != 'n' && month_3 != 'b' && month_3 != 'r' && month_3 != 'y' && month_3 != 'l' && month_3 != 'g' && month_3 != 'p' && month_3 != 't' && month_3 != 'v' && month_3 != 'c')
    {
        cout << "Invalid input, reenter the first 3 characters of the month: ";
        cin >> month_1 >> month_2 >> month_3;
        month_1 = toupper(month_1);
        month_2 = tolower(month_2);
        month_3 = tolower(month_3);
    }
}

void Month::assign1(int month)
{
    if (month == 1)
    {
        month1 = "Jan";
    }
    else if (month == 2)
    {
        month1 = "Feb";
    }
    else if (month == 3)
    {
        month1 = "Mar";
    }
    else if (month == 4)
    {
        month1 = "Apr";
    }
    else if (month == 5)
    {
        month1 = "May";
    }
    else if (month == 6)
    {
        month1 = "Jun";
    }
    else if (month == 7)
    {
        month1 = "Jul";
    }
    else if (month == 8)
    {
        month1 = "Aug";
    }
    else if (month == 9)
    {
        month1 = "Sep";
    }
    else if (month == 10)
    {
        month1 = "Oct";
    }
    else if (month == 11)
    {
        month1 = "Nov";
    }
    else if (month == 12)
    {
        month1 = "Dec";
    }
}
void Month::assign2(char month_1, char month_2, char month_3)
{
    if (month_1 == 'J')
    {
        if (month_2 == 'a')
        {
            if (month_3 == 'n')
            {
                month_int = 1;
            }
        }
        else if (month_2 == 'u')
        {
            if (month_3 == 'n')
            {
                month_int = 6;
            }
            else if (month_3 == 'l')
            {
                month_int = 7;
            }
        }
    }
    if (month_1 == 'F')
    {
        if (month_2 == 'e')
        {
            if (month_3 == 'b')
            {
                month_int = 2;
            }
        }
    }
    if (month_1 == 'M')  
    {
        if (month_2 == 'a')
        {
            if (month_3 == 'y')
            {
                month_int = 5;
            }
            else if (month_3 == 'r')
            {
                month_int = 3;
            }
        }
    }
    if (month_1 == 'A')
    {
        if (month_2 == 'p')
        {
            if (month_3 == 'r')
            {
                month_int = 4;
            }
        }
        else if (month_2 == 'u')
        {
            if (month_3 == 'g')
            {
                month_int = 8;
            }
        }
    }
    if (month_1 == 'S')
    {
        if (month_2 == 'e')
        {
            if (month_3 == 'p')
            {
                month_int = 9;
            }
        }
    }
    if (month_1 == 'O')
    {
        if (month_2 == 'c')
        {
            if (month_3 == 't')
            {
                month_int = 10;
            }
        }
    }
    if (month_1 == 'N')
    {
        if (month_2 == 'o')
        {
            if (month_3 == 'v')
            {
                month_int = 11;
            }
        }
    }
    if (month_1 == 'D')
    {
        if (month_2 == 'e')
        {
            if (month_3 == 'c')
            {
                month_int = 12;
            }
        }
    }
}
void Month::output(ostream& outs)
{
    outs << "Based on your number input, the month is " << month1 << ",\n";
    outs << "and based on your word input, it is month # " << month_int << " of the year.\n";
}

Month Month::next_month(ostream& outs)
{
    check_next_mo();
    cout << "The next month for your number input is " << new_month1 << ",\n";
    cout << "and the next month for your word input is month # " << new_month_int << ".\n";
}

void Month::check_next_mo()
{
    if (month1 == "Jan")
    {
        new_month1 = "Feb";
    }
    else if (month1 == "Feb")
    {
        new_month1 = "Mar";
    }
    else if (month1 == "Mar")
    {
        new_month1 = "Apr";
    }
    else if (month1 == "Apr")
    {
        new_month1 = "May";
    }
    else if (month1 == "May")
    {
        new_month1 = "Jun";
    }
    else if (month1 == "Jun")
    {
        new_month1 = "Jul";
    }
    else if (month1 == "Jul")
    {
        new_month1 = "Aug";
    }
    else if (month1 == "Aug")
    {
        new_month1 = "Sep";
    }
    else if (month1 == "Sep")
    {
        new_month1 = "Oct";
    }
    else if (month1 == "Oct")
    {
        new_month1 = "Nov";
    }
    else if (month1 == "Nov")
    {
        new_month1 = "Dec";
    }
    else if (month1 == "Dec")
    {
        new_month1 = "Jan";
    }
    
    new_month_int = month_int + 1;
    if (new_month_int == 13)
    {
        new_month_int = 1;
    }
}
My compiler wrote:
line 271: warning: no return statement in function returning non-void
Can I know what compiler you used by any chance?
So, I can just put return 0 in line 271, right?
So, I can just put return 0 in line 271, right?

No. Month::next_month is declared to return an object of type Month. So that's what it must return. Or change the function to type void and you don't have to return anything.

Overall, this is just ugly.

Why are new_month1 and new_month_int members of your class? An instance of a class should represent a single object i.e. a month.

It's generally not a good idea to keep multiple representations of an object in an instance. Instead, convert to an alternate representation (string) when needed.

I would suggest that your class contain only a single int value. i.e. The month it represents.

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

class Month
{   int     m_month;
public:
    Month();    // Default constructor
    Month (int mon);  // construct from int value

    void prompt_int();
    void prompt_abbrev ();
    void operator = (int month);
    void operator = (const string & abbrev);
    int operator ++ ();

    bool check1 (int month) const;
    int abbrev_to_int (const string & abbrev) const;
    friend ostream & operator << (ostream & os, const Month & mon);
};

int main( )
{   Month variable;

    variable.prompt_int();
    cout << variable << endl; 
    variable.prompt_abbrev ();
    cout << variable << endl; 
    ++variable;     // increment the month
    cout << "Next Month is: " << endl;
    cout << variable << endl; 
    system ("pause");
    return 0;
}

const string month_names[] = {"   ","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

//  Default constructor (January)
Month::Month()
{   m_month = 1;  
}


Month::Month (int mon)
{   m_month = mon;
}

void Month::prompt_int ()
{   int mon;

    do
    {   cout << "Enter a number 1-12 for the months: ";
        cin >> mon;
    }
    while (! check1 (mon));
    m_month = mon;
}

bool Month::check1 (int month) const
{   if (month >= 1 && month <= 12)
        return true;
    cout << "Invalid input, please enter a number 1-12 for the months: ";
    return false; 
}

void Month::prompt_abbrev ()
{   string abbrev;
    
    do 
    {   cout << "Enter the first 3 characters of the month: ";
        cin >> abbrev; 
        abbrev[0] = toupper(abbrev[0]);
        abbrev[1] = tolower(abbrev[1]);
        abbrev[2] = tolower(abbrev[2]);
        m_month = abbrev_to_int(abbrev);
    }
    while (! m_month); 
}

int Month::abbrev_to_int (const string & abbrev) const
{   for (int i=1; i<=12; i++)
        if (abbrev == month_names[i])
            return i;
    cout << "Invalid month abbreviation" << endl;
    return 0;
}

void Month::operator = (int month)
{   m_month = month; 
}

void Month::operator = (const string & abbrev) 
{   m_month = abbrev_to_int (abbrev); 
}

ostream & operator << (ostream & os, const Month & mon)
{   os << "The month is " << month_names[mon.m_month] << endl;
    os << "it is month # " << mon.m_month << " of the year." << endl;
    return os;
}

int Month::operator ++ ()
{   m_month++; 
    
    if (m_month == 13)
    {   m_month = 1;
    }
    return m_month;
} 




Actually, the problem said to input the first 3 initials of a month and the nth month of the year, and output the nth month equivalent to the 3-initial input and the 3-initial month equivalent to the nth month input.
Then, output the next month of each of the outputs.
Any ideas of doing this concisely?
Just tweak main() slightly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main( )
{   Month variable;

    //  Prompt for month by number
    variable.prompt_int();
    //  Display name & number of month 
    cout << variable << endl; 
    ++variable;     // increment the month      <- Added 
    cout << "Next Month is: " << endl;       // <- Added 
    cout << variable << endl;                     // <- Added 

    //  Prompt for month by abbrev.
    variable.prompt_abbrev ();
    //  Display month and number 
    cout << variable << endl; 

    ++variable;     // increment the month
    cout << "Next Month is: " << endl;
    cout << variable << endl; 
    system ("pause");
    return 0;
}
Enter a number 1-12 for the months: 3
The month is Mar
it is month # 3 of the year.

Next Month is:
The month is Apr
it is month # 4 of the year.

Enter the first 3 characters of the month: Dec
The month is Dec
it is month # 12 of the year.

Next Month is:
The month is Jan
it is month # 1 of the year.
Last edited on
eagle4022 wrote:
Can I know what compiler you used by any chance?

I use GCC. To get it to warn about missing return you need to use the -Wreturn-type option (one of many warning options enabled by -Wall).

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Is this a lot better?
The cout's in main are for formatting purposes, by the way.

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
	File: month_of_year.cpp 
	Description:
	Created: November 13, 2014
*/
#include <iostream>
#include <string>
#include <locale>

using namespace std;

const string month_abbrev[] = {" ", "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

class Month
{
public:
    Month();
    // Default constructor

    void enter_month();
    // Enters the month.

    void enter_abbrev();
    // Enters the abbreviation of the month.
    
    void output();
    // Outputs the month of the input to the user.

    Month next();
    // Gets the next month for the user.

    void next_output();
    // Outputs the next month to the user.

private:
    int month;
    string abbrev;
    
    int check1(int month_int);
    // Checks to make sure the input is valid.
    
    int check2(string abbrev_mo);
    // Checks to see if there is a match, and if there is, store the index of that match to the variable.
};

int main( )
{
	Month variable, next_index;
    int option;
    char ans;
    do
    {
        cout << "Enter 1 to input an integer for a month, or 2 to input a 3-letter abbreviation for a month: ";
        cin >> option;
        while (option != 1 && option != 2)
        {
            cout << "INVALID INPUT" << endl;
            cout << "Enter 1 to input an integer for a month, or 2 to input a 3-letter abbreviation for a month: ";
        }
        if (option == 1)
        {
            variable.enter_month();
            cout << endl;
            variable.output();
            next_index = variable.next();
            cout << endl;
            next_index.next_output();
            cout << endl;
        }
        else // if option == 2
        {
            variable.enter_abbrev();
            cout << endl;
            variable.output();
            next_index = variable.next();
            cout << endl;
            next_index.next_output();
            cout << endl;
        }
        cout << "Would you like to repeat the process?\n";
        cout << "Type in y for yes, and n for no: ";
        cin >> ans;
    } while (ans == 'y' || ans == 'Y');
    return 0;
}

Month::Month() : month(1)
{
}

void Month::enter_month()
{
    int value;
    cout << "Enter a number 1-12 for the month: ";
    cin >> month;
    value = check1(month);
    while (value == 0)
    {
        cout << "Not a valid input." << endl;
        cout << "Enter a number 1-12 for the month: ";
        cin >> month;
        value = check1(month);
    }
    month = value;
}

void Month::enter_abbrev()
{
    int value;
    cout << "Enter the first three initials of the month: ";
    cin >> abbrev;
    abbrev[0] = toupper(abbrev[0]);
    abbrev[1] = tolower(abbrev[1]);
    abbrev[2] = tolower(abbrev[2]);
    value = check2(abbrev);
    while (value == 0)
    {
        cout << "INVALID INPUT" << endl;
        cout << "Enter the first three initials of the month: ";
        cin >> abbrev;
        abbrev[0] = toupper(abbrev[0]);
        abbrev[1] = tolower(abbrev[1]);
        abbrev[2] = tolower(abbrev[2]);
        value = check2(abbrev);
    }
    month = value;
}

int Month::check1(int month_int)
{
    int value;
    if (month_int <= 0 || month_int > 12)
    {
        value = 0;
    }
    value = month_int;
    return value;
}

int Month::check2(string abbrev_mo)
{
    int not_equal = 0;
    for (int i = 1; i < 13; i++)
    {
        if (abbrev_mo == month_abbrev[i])
        {
            return i;
        }
    }
    return 0;
}

void Month::output()
{
    cout << "For your input, it is " << month_abbrev[month] << ",\n";
    cout << "which is month # " << month << " of the year.\n";
}

Month Month::next()
{
    Month month_nu; 
    month_nu.month = month + 1;
    if (month_nu.month == 13)
    {
        month_nu.month = 1;
    }
    return month_nu;
}

void Month::next_output()
{
    cout << "The next month will be " << month_abbrev[month] << ",\n";
    cout << "which is month # " << month << " of the year.\n";
}
Yes, that looks much better, although I did not not run it to see if it operates correctly.

I still disagree with keeping abbrev as a private member of your class. This may have been stipulated in your assignment, so it's not a big deal. Best practice is not to store multiple representations of the same data in a class unless it's expensive to convert from one to the other.
By the way, if you run it, you might get errors because of an infinite loop around line 55.
And yeah, the book recommended using private variables instead of public.
Thanks for all your help. I really appreciate it.
Also quick question, are goto statements that bad tp make my professor "vomit"?
Last edited on
are goto statements that bad tp make my professor "vomit"?

Short answer, yes.

Longer answer is they have a place, although very limited and not something recommended for beginners.
Topic archived. No new replies allowed.