Need help! User input to add to a .txt file

I'm writing a program that gives the user the option to display the first five names (one name on each line) on an existing names.txt file with a few dozen names, as well as display the last five names on the names.txt file. I'm having a hard time with the addNewNames() functions as when I go to enter a name and press enter, an infinite loop of !!! Choice out of range (1 - 5 only) comes up. I am writing a first and last name to the string. I would appreciate any help here :)

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

int getChoice();
void handleMenu(ifstream & fin);
void displayFirstFive(ifstream & fin);
void displayLastFive(ifstream & fin);
int count(ifstream & fin);
void addNewNames();


int main()
{
	ifstream fin;

	fin.open("names.txt", ios::in);
	handleMenu(fin);
	fin.close();

	cout << "Over!" << endl;
	system("PAUSE"); // program does not pause when finished without this line
	return 0;
}
int getChoice()
{
	int choice;

	cout << "\nEnter your choice: ";
	cin >> choice;

	while (choice < 1 || choice > 5)
	{
		cout << "!!! Choice out of range (1 - 5 only) ";
		cin >> choice;
	}
	return choice;
}
void handleMenu(ifstream & fin)
{
	string line(45, '*');
	int choice,
		numOfLines;
	do
	{
		cout << line << endl;
		cout << "1.Display first five names\n"
			<< "2.Display last five names\n"
			<< "3.Count the number of names\n"
			<< "4.Add a new name\n"
			<< "5.Quit\n";
		cout << line << endl;

		choice = getChoice();

		if (choice == 1)
		{
			displayFirstFive(fin);
		}

		else if (choice == 2)
		{
			displayLastFive(fin);
		}

		else if (choice == 3)
		{
			numOfLines = count(fin);

			cout << "There are " << numOfLines << " names\n\n";
		}
		else if (choice == 4)
		{
			addNewNames();
		}
	} while (choice != 5);
}
void displayFirstFive(ifstream & fin)
{
	string line;
	int count = 0;

	fin.clear();
	fin.seekg(0, ios::beg);

	if (fin.is_open())
	{
		while (getline(fin, line) && count < 5)
		{
			cout << count + 1 << ":" << line << endl;
			count++;
		}
	}

	else
	{
		cout << "Could not open file" << endl;
	}
	
	cout << endl;
}

void displayLastFive(ifstream & fin)
{
	string line;
	int counter = 0,
		total;

	total = count(fin);

	fin.clear();
	fin.seekg(0, ios::beg);

	while (getline(fin, line))
	{
		counter++;

		if (counter >= total - 4)
		{
			cout << counter << ":" << line << endl;
		}
	}

	cout << endl;
}
int count(ifstream & fin)
{
	int numOfLines = 0;
	string line;


	while (getline(fin, line))
	{
		numOfLines++;
	}

	return numOfLines;
}
void addNewNames()
{
	string input;
	ofstream fin;

	fin.open("names.txt", ios::out | ios::app);

	cout << "Adding a name\n";
	cout << "Enter a name ";

	getline(cin, input);
	cin.ignore();

	fin << endl << input << endl;

}
Last edited on
I'm having a hard time with the addNewNames() functions as when I go to enter a name and press enter, an infinite loop of !!! Choice out of range (1 - 5 only) comes up
1
2
3
4
5
6
7
8
9
10
string input;
ofstream fin;

fin.open("names.txt", ios::out | ios::app);

cout << "Adding a name\n";
cout << "Enter a name ";

getline(cin, input);
cin.ignore();

- You open an already opened file (as input) again (this time as output). It becomes hard to deal with.
- You may just specify std::ios_base::app, without “out”.
- The less you mix std::cin >> and std::getline(std::cin, ...) the better. I‘m afraid the following cin.ignore(); closes the stable door after the horse has bolted :-(
Have a look here:
http://www.cplusplus.com/forum/general/69685/#msg372532

Hints:
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
// I'm writing a program that gives the user the option to display the first 
// five names (one name on each line) on an existing names.txt file with a 
// few dozen names, as well as display the last five names on the names.txt 
// file. I'm having a hard time with the addNewNames() functions as when I go 
// to enter a name and press enter, an infinite loop of !!! Choice out of 
// range (1 - 5 only) comes up. I am writing a first and last name to the 
// string. I would appreciate any help here :)
#include <iostream>
#include <fstream>
#include <limits>
#include <string>

void handleMenu(const std::string& filename);
int getChoice();
void displayFirstFive(std::fstream & fin);
void displayLastFive(std::fstream & fin);
int count(std::fstream & fin);
void addNewNames(std::fstream & fin);

int main()
{
    std::string filename { "names.txt" };
    handleMenu(filename);
    std::cout << "Over!\n";
//    system("PAUSE"); // http://www.cplusplus.com/forum/beginner/1988/
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return 0;
}

void handleMenu(const std::string& filename)
{
    std::string line(45, '*');
    int choice = 0;
    do {
        std::cout << line << '\n';
        std::cout << "1. Display first five names\n"
                     "2. Display last five names\n"
                     "3. Count the number of names\n"
                     "4. Add a new name\n"
                     "5. Quit\n";
        std::cout << line << '\n';

        choice = getChoice();
        std::fstream fin(filename);
        if(!fin) {
            std::cout << "can't open " << filename << ".\n";
            return;
        }
        // switch?
        if      (choice == 1) { displayFirstFive(fin); }
        else if (choice == 2) { displayLastFive(fin); }
        else if (choice == 3) { std::cout << "There are " << count(fin) << " names\n\n"; }
        else if (choice == 4) { addNewNames(fin); }
    } while (choice != 5);
}

int getChoice()
{
    std::cout << "\nEnter your choice: ";
    int choice = 0;
    std::cin >> choice;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    while (choice < 1 || choice > 5)
    {
        std::cout << "!!! Choice out of range (1 - 5 only). Try again: ";
        std::cin >> choice;
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    return choice;
}

void displayFirstFive(std::fstream & fin)
{
    fin.clear();
    fin.seekg(0, std::ios::beg);

    std::string line;
    int count = 0;
    while (std::getline(fin, line) && count < 5)
    {
        std::cout << count + 1 << ": " << line << '\n';
        count++;
    }
    std::cout << '\n';
}

void displayLastFive(std::fstream & fin)
{
    int total = count(fin), counter = 0;
    fin.clear();
    fin.seekg(0, std::ios::beg);
    std::string line;
    while (std::getline(fin, line))
    {
        counter++;
        if (counter > total - 5) { std::cout << counter << ": " << line << '\n'; }
    }
    std::cout << '\n';
}

int count(std::fstream & fin)
{
    fin.clear();
    fin.seekg(0, std::ios::beg);

    int numOfLines = 0;
    std::string line;
    while (std::getline(fin, line)) { numOfLines++; }
    return numOfLines;
}

void addNewNames(std::fstream& fin)
{
    fin.clear();
    fin.seekg(0, std::ios::end);
    std::cout << "Adding a name\nEnter a name: ";
    std::string input;
    getline(std::cin, input);
    fin << input << '\n';
}

Registered users can post here. Sign in or register to post.