Help with reading a txt file into an array

I need help trying to print out the array of last names from a txt file.
What I'm supposed to do is have the user input the size of the array,
then the the file is read and gets each line of last names and puts them into the array.

The txt file has like 1000 names, but I put a size cap so the user cant go over 500.

So if the user inputs 250, I should be able to see 250 names listed.

It's able to print the names but it goes in an infinite loop.

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
#include <cstdlib>
#include "pch.h"
#include "Qqueue.h" //documenton is in the header file
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
	const int CAP = 500;
	string arrayLast[CAP];
	int userCap;
	int* queue = new int[CAP];

	ifstream file_;
	string lastname;

	file_.open("all.last.txt");
	if (file_.fail())
	{
		cout << "\nError opening file";
		return 1;
	}

	cout << "\nType the number of of names you want to insert into the queue.";
	cout << "\n The max capacity is 500 and the input must be atleast >= 100" << endl;
	cin >> userCap;

	if (userCap > CAP)
	{
		cout << "\nQueue requested is too large.";
		return 0;
	}
	else if (userCap < 100)
	{
		cout << "\nQueue is too little. Must be atleast 100 or more.";
		return 0;
	}

	//int i = 0;
	while (!file_.eof())
	{
		getline(file_, arrayLast[userCap]);
		
		cout << arrayLast[userCap] << endl;
	}

	file_.close();

	system("Pause");
	return 0;
}
Last edited on
first,
while !file.eof does not work.
recommended:
while (file.getline(…) ) format.

but you don't need to do it this way.
you should use a for loop.
you KNOW that the file has more records than you will read.
so read the # of records the user asked for.

also, usercap does NOT CHANGE in your loop. You are overwriting the same value again and again. it needs a ++ somewhere -- since you be swapping to a for loop, use it AS the loop variable... right? EDIT: I am ok with 'contracted' code, that is you promised the file had more than we will read, so for loop is ok. Andy's code below is safer; it checks end of file without that trust/contract that mine required. Ive written a lot of contracted code, but it was talking to other computers/devices, where the odds of a broken contract were zero (barring complete hardware malfunction, at which point, it didnt matter anymore).
Last edited on
Hello orichalcum,

The variable "queue" I do not understand what this is for or what idea you have for it. Also I do not see it used anywhere in the program.

if (file_.fail()). It is not the best idea to end a variable name with an underscore. When I first saw it I was thing that something was missing. The "file_.fail()" can be shortened to "!file_" and work just fine.

I will give you a gold star for using code tags and checking if the file stream did open in good condition. And also for the use of the "return 1;".

Line 42 is a good idea, although I would most likely call it "count" and not "i".

You were doing good until the while loop. the condition of "!file_.eof()" does not work the way you are thinking. By the time the condition figures out that you are at "eof" you will have processed your last read twice.

The use of arrayLast[userCap]. Right idea wrong approach. By using the variable "userCap" you are putting each read into the same element of the array and that is not what you want.

This should work better for you:
1
2
3
4
5
6
7
8
int count{};

while (std::getline(file_, arrayLast[count]) && count < userCap)
{
	std::cout << arrayLast[count] << std::endl;

	count++;
}

This should work better for you. I have to find my file of names to test it, But I believe it should work.

Using "system" anything is not good. It can leave the program with the ability to be hacked. For a replacement I use this:
1
2
3
4
// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
std::cout << "\n\n Press Enter to continue: ";
std::cin.get();

It tends to work well.

Hope that helps,

Andy
@Andy, the tests in your while loop should be the other way around lest an extra line is read before it is noticed that count is no longer < userCap.
@dutch,

Thank you for the input. I can see the truth in what you are saying and I will remember that for the future. Though in my defense I was recalling several examples I have seen here.

@orichalcum,

jonnin's post came through before I finished what I was working on and I missed out on his insight.

jonnin's for loop would work, but I was thinking ahead to a time whenyou might have to read more than 500 names. In which case you would reach "eof" before you wanted to. Say the file should contain 1000 names, but actually contains 999 names you would reach "eof" before you expected to.

I did a little rework of your code 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
//#include "pch.h"
//#include <cstdlib> // <--- In VS this is included through <iostream>.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

//#include "Qqueue.h" //documenton is in the header file

//using namespace std;  // <--- Best not to use.

int main()
{
	const int CAP{ 506 }; // <--- Increased to allow the for loop to work.
	//const std::string PATH{ "F:/Text Files/" };

	std::string arrayLast[CAP];
	int userCap{};
	//int* queue = new int[CAP];

	std::ifstream file_;
	std::string lastname;

	file_.open("all.last.txt");
	//file_.open(PATH + "500 Random Names.txt");

	if (file_.fail())
	{
		std::cout << "\nError opening file";
		return 1;
	}

	std::cout << "\n Type the number of of names you want to insert into the queue.";
	std::cout << "\n The max capacity is 500 and the input must be atleast >= 100: ";
	std::cin >> userCap;
	std::cout << '\n';

	//if (userCap > CAP)
	//{
	//	std::cout << "\nQueue requested is too large.";
	//	return 2;
	//}
	//else if (userCap < 100)
	//{
	//	std::cout << "\nQueue is too little. Must be atleast 100 or more.";
	//	return 3;
	//}

	int count = 0;

	while (count < userCap && getline(file_, arrayLast[userCap]))
        //while (count < userCap && getline(file_, arrayLast[count]))
	{
		std::cout << std::setw(3) << count + 1 << "  " << arrayLast[count] << std::endl;

		count++;
	}

	std::cout << "\n\n The array contains:\n Element  Contents" << std::endl;

	for (int lc = 0; lc < userCap + 5; lc++)
	{
		std::cout << std::setw(5) << lc << "     " << arrayLast[lc] << std::endl;
	}

	file_.close();

	// <--- Used to as a replacement for "system("pause")".
	// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue: ";
	std::cin.get();

	return 0;
}

I had to comment out some of the code as I either did not need it or have it. Your program uses the header file "Qqueue.h", but you neglected to provide it. But that is OK there appears to be nothing in the code that uses anything from this header file. In the future if a program needs a header file that is not a standard C++ header file you need to include it in your post.

For the header files.

It has been said that the order of the "#include" files should not make any difference, but sometimes it does.

I believe that VS likes to have the "#include "pch.h" first. It has been awhile since I have used VS with the "pch.h" file. These days I just create an empty solution/project.

Putting the (#include "Qqueue.h") last allows for the preceding header files to cover anything that "Qqueue.h" may need. Since that code is loaded after the other header files.

For the purpose of this code I had to change the size of "CAP". Later you can change it back to 500.

Lines 15 and 25 I left as an example of what you can do should you ever need to provide a path to a file.

I had to comment out the if/else if as it is more of a hindrance right now.

Lines 59 - 64 I added to show what is actually in the array and where the names are actually being stored.

After you have run this switch the comments on lines 51 and 52 and see the difference in what is in your array.

The for loop and line 59 can be removed when you are done with your testing.

Hope that helps,

Andy
Thank you so much @Andy!!!

I did both tests and saw exactly what you did here and it's also the solution to my problem.It works perfectly.Also thanks to the others that have responded.

I figured it had to do with the while loop and missing count, but I didn't include (which why I commented it out for now) because I wasn't sure if that was the issue, but I wanted to check.
I'm also using visual stdio and it had the pch header attached so I basically had to include it or it will throw an error.

I just needed to test this part so I know the queue can be created with user input. The queue header file contains the functions I need to start doing FIFO to the array , but I have't started on that yet so that's why I didn't use anything from it just yet.
Topic archived. No new replies allowed.