Program crashes using getline

Im stuck on a function for a program im creating to help keep track of my workouts. Im using the STL list, but for some reason the program crashes once it reaches the comments section. Thanks a ton if you can help!

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
void AddRoutine(list<Workout>& wrkout)
{
    Workout tempObj;
    char tempData[5];

    std::cout << "What is the date today?(00/00/00) ";
    std::cin >> tempObj.Date;

    std::cout << "Type of workout today?(SWIM/RUN/BIKE) ";
    std::cin >> tempData;
    tempObj.TYPE = ConvertEnum(tempData);

    std::cout << "Distance? ";
    std::cin >> tempObj.distance;

    std::cout << "Units? ";
    std::cin >> tempObj.units;

    std::cout << "Additional comments about this exercise?(up to 100 characters) ";
    getline(std::cin,tempObj.comments);

    wrkout.push_back(tempObj);
    UpdateData(wrkout);

}


Entire program(unfinished):
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
#include <iostream>
#include <fstream>
#include <list>
#include <iomanip>
#include <windows.h>
#include <cstring>
#include <string>
#define TAB 12

///ADD TIMER CLASS

struct Workout
{
    int TYPE;
    float distance;
    char Date[10];
    std::string comments;
    char units[10];
};

using std::list;
enum TYPES{ADD = 1, REMOVE, EDIT, EXIT, SWIM, BIKE, RUN};
enum ACTION{INT_TO_ENUM, ENUM_TO_INT};

void cls();
bool Goodinput(int choice);
void AddRoutine(list<Workout>& wrkout);
void DeleteRoutine(list<Workout>& wrkout);
void EditRoutine(list<Workout>& wrkout);
void UpdateData(list<Workout>& wrkout);
void DisplayCalender(list<Workout>& wrkout);
char * ConvertEnum(int TYPE);
int ConvertEnum(char * TYPE);

int main()
{
    bool Running = true;
    list<Workout> wrkout;
    std::cout << "Exercise Tracker v0.1 C++ Code::Blocks - Grant Mercer\n";
    while(Running)
    {
        int choice = 0;
        DisplayCalender(wrkout);
        std::cout << "[1] Add an exercise    [2] Edit an exisiting exercise\n"
                  << "[3] Remove an exercise [4] Exit\n";
        std::cin >> choice;

        switch(choice)
        {
            case ADD:
                AddRoutine(wrkout);
                break;
            case REMOVE:
                DeleteRoutine(wrkout);
                break;
            case EDIT:
                EditRoutine(wrkout);
                break;
            case EXIT:
                return 0;
                break;
            default:
                std::cerr << "Invalid input, please try again...\n";
                break;
        }
        UpdateData(wrkout);
        cls();
    }

    return 0;
}

bool Goodinput(int choice)
{
    return true;
}

void AddRoutine(list<Workout>& wrkout)
{
    Workout tempObj;
    char tempData[5];

    std::cout << "What is the date today?(00/00/00) ";
    std::cin >> tempObj.Date;

    std::cout << "Type of workout today?(SWIM/RUN/BIKE) ";
    std::cin >> tempData;
    tempObj.TYPE = ConvertEnum(tempData);

    std::cout << "Distance? ";
    std::cin >> tempObj.distance;

    std::cout << "Units? ";
    std::cin >> tempObj.units;

    std::cout << "Additional comments about this exercise?(up to 100 characters) ";
    getline(std::cin,tempObj.comments);

    wrkout.push_back(tempObj);
    UpdateData(wrkout);

}

void DeleteRoutine(list<Workout>& wrkout)
{
    char dte[10];
    std::cout << "Please enter the date you wish to remove(Format 00/00/00): ";
    std::cin >> dte;
    for(list<Workout>::iterator iter = wrkout.begin(); iter != wrkout.end(); iter++)
    {
        if(iter->Date == dte)
        {
            wrkout.erase(iter++);
        }
    }
    UpdateData(wrkout);
}

void EditRoutine(list<Workout>& wrkout)
{

}

void UpdateData(list<Workout>& wrkout)
{
    std::ofstream File("Data.txt");
    for(list<Workout>::iterator iter = wrkout.begin(); iter != wrkout.end(); iter++)
    {
        File << iter->Date << " " << ConvertEnum(iter->TYPE) << " " << iter->distance
             << " " << iter->units << " " << iter->comments << std::endl;
    }
}
void DisplayCalender(list<Workout>& wrkout)
{
    using std::setw;

    std::cout << std::left
    << setw(TAB) << "Date"
    << setw(TAB) << "Type"
    << setw(TAB) << "Distance"
    << setw(TAB) << "Units"
    << setw(TAB) << "Additional Comments\n";

    for(list<Workout>::iterator iter = wrkout.begin(); iter != wrkout.end(); iter++)
    {
        std::cout << std::left
        << setw(TAB) << iter->Date
        << setw(TAB) << ConvertEnum(iter->TYPE)
        << setw(TAB) << iter->distance
        << setw(TAB) << iter->units
        << setw(TAB) << "Select to review\n";
    }
}

char * ConvertEnum(int TYPE)
{
    char * temp;
        switch(TYPE)
        {
            case SWIM:
                strncpy("SWIM",temp,4);
            case RUN:
                strncpy("RUN",temp,3);
            case BIKE:
                strncpy("BIKE",temp,4);
            default:
                strncpy("ERROR",temp,5);
        }
    return temp;
}

int ConvertEnum(char * TYPE)
{

        if(strcmp(TYPE,"SWIM") == 0)
            return SWIM;
        else if(strcmp(TYPE,"BIKE") == 0)
            return BIKE;
        else if(strcmp(TYPE,"RUN") == 0)
            return RUN;
        else
            return SWIM;

}
void cls() //windows h function to replace screen with nulls
{
  DWORD n;
  DWORD size;
  COORD coord = {0};
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE );
  GetConsoleScreenBufferInfo ( h, &csbi );
  size = csbi.dwSize.X * csbi.dwSize.Y;
  FillConsoleOutputCharacter ( h, TEXT ( ' ' ), size, coord, &n );
  GetConsoleScreenBufferInfo ( h, &csbi );
  FillConsoleOutputAttribute ( h, csbi.wAttributes, size, coord, &n );
  SetConsoleCursorPosition ( h, coord );
}
Last edited on
instead of
getline(std::cin, tempObj.comments);
why dont you use
1
2
3
string comments;
std::cout << "Additional comments about this exercise? (up to 100 characters)";
std::cin >> comments;
Last edited on
I don't see anything wrong with your code...what is the exact message you are getting when it crashes?
1
2
3
4
//char * ConvertEnum(int TYPE)
char * temp;
strncpy("SWIM",temp,4);
//char *strncpy(char *destination, const char *source, size_t n); 
It shouldn't compile, and temp has garbage.

You could just
1
2
3
4
5
6
7
8
9
10
11
12
13
std::string ConvertEnum(int TYPE){
        switch(TYPE)
        {
            case SWIM:
                return "SWIM";
            case RUN:
                return "RUN";
            case BIKE:
                return "BIKE";
            default:
                return "ERROR";
        }
}
Last edited on
I need to use getline because the user will enter a short paragraph to be stored in comments, not just a word.

The program does not give an error, it only crashes and tells me its not responding when i reach the part to enter into the comments variable
It's strncpy that fails, you reversed the parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char * ConvertEnum(int TYPE)
{
     char * temp = new char[20];
        switch(TYPE)
        {
            case SWIM:
                strncpy(temp,"SWIM",5);
		break;
            case RUN:
                strncpy(temp,"RUN",3);
		break;
            case BIKE:
                strncpy(temp,"BIKE",4);
		break;
            default:
                strncpy(temp,"ERROR",5);
        }
    return temp;
}


http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
Last edited on
Topic archived. No new replies allowed.