First question in a while

Aight, so a friend asked me to write an organizer program with the vector class.

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

class ydm_notes
{
    int year;
    short day;
    short month;
    string notes;
    public:
    ydm_notes() {}
    ydm_notes(int m_year, short m_day, short m_month, string m_notes) : 
    day (m_day), month (m_month), year (m_year), notes(m_notes) {}
    ~ydm_notes() {}
    friend ostream & operator<<(ostream &, ydm_notes);
    friend istream & operator>>(istream &, ydm_notes);
    friend vector<ydm_notes> sort(vector<ydm_notes> vect);
    friend ydm_notes getfirst(vector<ydm_notes> vect);
    void input(istream & in)
    {
        cout << "Year: ";
        in >> year;
        cout << "Day: ";
        in >> day;
        cout << "Month: ";
        in >> month;
        cout << "Day's notes: ";
        in.ignore(numeric_limits<streamsize>::max(), '\n');
        getline(in, notes);
    }
};

ostream & operator<<(ostream & out, ydm_notes obj)
{
    out << obj.year << " " << obj.day << " " << obj.month << " notes: " << obj.notes << endl;
    return out;
}

istream & operator>>(istream & in, ydm_notes obj)
{
    in >> obj.year;
    in >> obj.day;
    in >> obj.month;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cin.ignore(numeric_limits<streamsize>::max(), ':');
    getline(in, obj.notes);
    return in;
}

vector<ydm_notes> sort(vector<ydm_notes> vect)
{
    vector<ydm_notes> vect2;
    vect2.push_back(getfirst(vect));
    return vect2;
}

ydm_notes getfirst(vector<ydm_notes> vect)
{
    
    for(int i = vect.size(); i > 0; i--)
    {
        for(int j = i; vect[j].year < vect[j-1].year; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
        for(int j = i; vect[j].year < vect[j-1].year; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
        for(int j = i; vect[j].month < vect[j-1].month; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
    }
    return vect[0];
}

void editor(vector<ydm_notes> & vect, string file);

int main()
{
    vector<ydm_notes> notesh;
    while(true)
    {
    cout << "1: New File\n"
         << "2: Load File\n"
         << "3: Exit\n>";
    int choice;
    cin >> choice;
    if(!cin || (choice < 1 || choice > 4) )
    {
    cout << "Invalid input. Press ENTER to continue.\n";
    cin.clear();
    cin.sync();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    continue;
    }
    else if(choice == 3)
        return 0;
    else if(choice == 2)
    {
        cout << "File to load?\n(Full path. NOTE: use 2 backslashes (\"\\\") between folders for engine reasons.)\n>";
        string file;
        getline(cin, file);
        editor(notesh, file);
        continue;
    }
    else if(choice == 1)
    {
        editor(notesh, "\0");
    }
    }
}

void editor(vector<ydm_notes> & vect, string file)
{
    fstream FileStream;
    cout << "How many notes to log?\n";
    int num;
    cin >> num;
    for(int i = 0; i < num; i++)
    {
        vect[i].input(cin);
    }
    if(file != "\0")
    FileStream.open(file.c_str(), ios::in | ios::out);
    else
    {
        cout << "File to save to?\n(Full path. NOTE: use 2 backslashes (\"\\\") between folders for engine reasons.)\n>";
        getline(cin, file);
        FileStream.open(file.c_str(), ios::in | ios::out);
    }  
    for(int i = num; !FileStream.eof(); i++)
    FileStream >> vect[i];
    sort(vect);
    for(int i = 0; i < vect.size(); i++)
    FileStream >> vect[i];
}


At the input() function (yeah, yeah, I was in a rush, hence the single file, mid-class stuff), it asks for the year, I input the year, and...it freezes. I'm not sure why, I've looked over the code and such.

If it matters, the function itself is at line 23, and it's called at 136.

Thanks in advance. :D

EDIT: It's segfaulting at line 25, found that out after running a debugger.
Last edited on
Hi, you should change this function like this:
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
void editor(vector<ydm_notes> & vect, string file)
{
    fstream FileStream;
    cout << "How many notes to log?\n";
    int num;
    cin >> num;
    for(int i = 0; i < num; i++)
    {
        ydm_notes tmp;
		tmp.input(cin);
		vect.push_back(tmp);
    }
    if(file != "\0")
		FileStream.open(file.c_str(), ios::in | ios::out);
    else
    {
        cout << "File to save to?\n(Full path. NOTE: use 2 backslashes (\"\\\") between folders for engine reasons.)\n>";
        getline(cin, file);
        FileStream.open(file.c_str(), ios::in | ios::out);
    }  
    for(int i = num; !FileStream.eof(); i++)
		FileStream >> vect[i];
    sort(vect);
    for(int i = 0; i < vect.size(); i++)
		FileStream >> vect[i];
}

in this for scope,

for(int i = 0; i < num; i++)
{
ydm_notes tmp;
tmp.input(cin);
vect.push_back(tmp);
}

you can not use vect[index], because at this time, the vector is empty, you did not push any date in it, so you can not access it also.
so you need to save the input data in a temp variable, then push it in to vector.
Ah, another segfault, this time at line 143. But your suggestion worked.

EDIT: Hmm. Maybe it's 'cause of the full path needing.

EDIT: Nope. But there seems to be a problem with line 57, if that helps anyone.
Last edited on
You have at least a couple of problems it appears.

One is which it looks like you index your vectors 1...size whereas in fact it is 0...size-1.

Another I think with fetag's code is that vect[] better have elements preallocated in
order for lines 21-22 and 24-25 to work.
Major editing. But still it segfaults, and after debugging, it has proven to be within the sort() 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
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
#include <fstream>
#include <iostream>
#include <limits>
#include <string>
#include <vector>
using namespace std;

class ydm_notes
{
    int year;
    short day;
    short month;
    string notes;
    public:
    ydm_notes() {}
    ydm_notes(int m_year, short m_day, short m_month, string m_notes) : 
    day (m_day), month (m_month), year (m_year), notes(m_notes) {}
    ~ydm_notes() {}
    friend ostream & operator<<(ostream &, ydm_notes);
    friend istream & operator>>(istream &, ydm_notes);
    friend void sort(vector<ydm_notes> & vect);
    friend ydm_notes getfirst(vector<ydm_notes> vect);
    void input()
    {
        cout << "Year: ";
        cin >> year;
        cout << "Day: ";
        cin >> day;
        cout << "Month: ";
        cin >> month;
        cout << "Day's notes: ";
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        getline(cin, notes);
    }
};

ostream & operator<<(ostream & out, ydm_notes obj)
{
    out << obj.year << " " << obj.day << " " << obj.month << " notes: " << obj.notes << endl;
    return out;
}

istream & operator>>(istream & in, ydm_notes obj)
{
    in >> obj.year;
    in >> obj.day;
    in >> obj.month;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cin.ignore(numeric_limits<streamsize>::max(), ':');
    getline(in, obj.notes);
    return in;
}

void sort(vector<ydm_notes> & vect)
{
    vect[0] = getfirst(vect);
}

ydm_notes getfirst(vector<ydm_notes> vect)
{
    
    for(int i = vect.size()-1; i >= 0; i--)
    {
        for(int j = i; vect[j].year < vect[j-1].year; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
        for(int j = i; vect[j].year < vect[j-1].year; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
        for(int j = i; vect[j].month < vect[j-1].month; j--)
        {
        ydm_notes temp;
        temp = vect[i];
        vect[i] = vect[i-1];
        vect[i-1] = temp;
        }
    }
    return vect[0];
}

void editor(vector<ydm_notes> & vect, string file);

int main()
{
    vector<ydm_notes> notesh;
    while(true)
    {
    cout << "1: New File\n"
         << "2: Load File\n"
         << "3: Exit\n>";
    int choice;
    cin >> choice;
    if(!cin || (choice < 1 || choice > 4) )
    {
    cout << "Invalid input. Press ENTER to continue.\n";
    cin.clear();
    cin.sync();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    continue;
    }
    else if(choice == 3)
        return 0;
    else if(choice == 2)
    {
        cout << "File to load?\n>";
        string file;
        getline(cin, file);
        editor(notesh, file);
        continue;
    }
    else if(choice == 1)
    {
        editor(notesh, "\0");
    }
    }
}

void editor(vector<ydm_notes> & vect, string file)
{
    fstream FileStream;
    cout << "How many notes to log?\n";
    int num;
    cin >> num;
    for(int i = 0; i < num; i++)
    {
        ydm_notes temp;
        temp.input();
        vect.push_back(temp);
    }
    if(file != "\0")
    FileStream.open(file.c_str(), ios::in | ios::out);
    else
    {
        cout << "File to save to?\n>";
        getline(cin, file);
        FileStream.open(file.c_str(), ios::in | ios::out);
    }  
    
    for(int i = num; !FileStream.eof(); i++)
    {
    ydm_notes tmp;
    FileStream >> tmp;
    vect.push_back(tmp);
    }
    sort(vect);
    for(int i = 0; i < vect.size(); i++)
    FileStream << vect[i];
}
    
Can you explain what cin.clear(), cin.sync(); and if(!cin) means please?
cin.clear() clears the input stream.
cin.sync() discards any more unread characters in the buffer.

if(!cin) requires a bit more explanation.

In the statement cin >> choice;, since choice is an integer, cin expects an integer response. If someone were really stupid and inputted "w" or some other character or symbol besides a number, cin sets the failbit, causing the return value of cin to be false, and allowing no more input to be accepted unless the buffer is cleared.

And that's where cin.clear() and cin.sync() come in.
Thank you for the information.

Edit ** Sorry last question... is there anyway to write a program where if the user doesn't input anything and just presses enter, you get an error message instead of it skipping down to the next line and continue to wait for an input?
Last edited on
Wait...is it not segfaulting for you? Because it still does for me, within the sort() function.

And as for your question, I can't think of any way ATM, but there probably is.
Debugging segfaults is typically pretty easy. What have you learned by debugging? Simply step through the code line by line until it crashes and then remember that. set a breakpoint right before the line where the crash occurs and re-run until that point. Analyze the contents of the containers.

I find the sort function to be very strange.
void sort(vector<ydm_notes> & vect)
1
2
3
4
5
6
{
    // getFirst copies the vect object and all changes made wtihin getFirst are then lost.
    // when it returns the first element of the sorted vector is copied into the original 
    // vector but the other changes within getFirst are lost.
    vect[0] = getfirst(vect);
}


I guess I don't understand the point of all the copying in the getFirst function if you aren't keeping the sorted container (provided that the sort actually works in the first place). Although I don't see any smoking gun that would cause the crash, I would bet that stepping into the code with the debugger would lead to finding the problem. Good luck!
Topic archived. No new replies allowed.