Hello iamkairos,
PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.
Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/
Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.
You can use the preview button at the bottom to see how it looks.
I found the second link to be the most help.
|
I found that there are a couple of places where you have some extra blank lines that you do not need and a couple of places where you do. That will come with time and more use of your IDE and how it works.When I put your code in my IDE it was refreshing to see code that is easy to read.
The struct is good and I do agree with
keskiverto that the struct if for one movie, so the name should be "Movie" to be more accurate. Notice that the first is a capital letter. Many tend to start classes and structs with a capital letter, but you are free to use a variable name any way you want.
I do have a question about
double moviesRating;
. Why the "double"? Without having a better understand I feel this is over kill for something that is likely to hold a number of 1 to 7. I am thinking a 'short" or an "int" would be a better choice.
For an example:
1 2 3 4 5 6 7
|
void displayMenuSpecific(struct movies movieInfo[], int total)
{
for (int i = 0; i < total; i++)
{
cout << movieInfo[i].moviesName;
}
};
|
The semi-colon after the closing brace of the function is not needed. If I understand this the closing } ends the function not the semi-colon. I do not believe it will cause any problem if you leave it.
In "main" you have:
1 2 3 4
|
if (!inputLibrary)
{
cout << "ERROR: File not found! " << endl;
}
|
The concept is good, but the implementation is wrong. If the file stream did not open you would continue on with the program wondering why it did not work. What you want is something more like this:
1 2 3 4 5 6
|
if (!inputLibrary)
{
std::cerr << "ERROR: File \"program2_library\" not found! " << endl;
return 1;
}
|
The "return" statement will leave the program because there is no point in continuing until you fix the problem. Any number greater than zero indicates the the program ended with a problem. Using a different number can help to indicate what or where the problem is.
For another option I like using this:
1 2 3 4 5 6 7 8 9 10 11
|
//testing if my file is found
const std::string inFileName{ "program2_library.txt" };
ifstream inputLibrary(inFileName);
if (!inputLibrary)
{
std::cerr << "ERROR: File " << std::quoted(inFileName) << " not found! " << endl;
return 1;
}
|
In both examples I used "cerr" in place of "cout". As it was pointed out to me "cout" can be redirected to something other than the screen whereas "cerr" is not likely to be changed.
By defining the file name as a constant variable you only have one place to change the name to be used in 2 or more places in the program. It is similar to the variable "MAX_MOVIES".
The "std::quoted" is from the "iomanip" header file and if someone does not tell you about it you may never know what it is for. This function will put double quotes around what is in the (), be it a variable or a constant string, ("program2_library.txt").
Changing the name of the struct to "Movie" you could change the name of the array to
Movie movies[MAX_MOVIES];
. Just a suggestion. What you have works.
As
keskiverto pointed out the use of
while (!inputLibrary.eof())
is not a good idea. It does not work the way that you are thinking and it is being used wrong.
When you get to the while loop the "eof" bit is not set, so you enter the loop and read the first bit of information which may set the "eof" bit, but you still store what you can not read before the while condition picks on the "eof" bit being set and fails.
Over time I have come to the conclusion that people are taught about the ".eof()" function, but not how to properly use it. If yo insist on or have to use the ".eof()" function you will need to do this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
getline(inputLibrary, movieInfo[total].moviesId);
while (!inputLibrary.eof())
{
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesName);
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesActor1);
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesActor2);
inputLibrary >> movieInfo[total].moviesYear;
inputLibrary >> movieInfo[total].moviesRating;
total++;
getline(inputLibrary, movieInfo[total].moviesId);
}
|
If the first read line 1 sets the "eof" bit the while loop will fail. Line 13 will read the beginning of the next record and if that sets the "eof" bit the while condition will catch this at the proper time.
What is used more often to read a file of unknown length is:
1 2 3 4 5 6 7 8 9 10
|
while (getline(inputLibrary, movieInfo[total].moviesId))
{
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesName);
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesActor1);
inputLibrary >> ws; getline(inputLibrary, movieInfo[total].moviesActor2);
inputLibrary >> movieInfo[total].moviesYear;
inputLibrary >> movieInfo[total].moviesRating;
total++;
}
|
This way when the read fails so does the loop.
inputLibrary >> ws;
This should not be necessary, but I do not know what your file looks like. If you need it you could write it like this:
getline(inputLibrary >> ws, movieInfo[total].moviesId)
and it would work just the same.
As it has been pointed out your sort portion is not workable.
Thing about the for loops with an array having a size of 5 elements, numbered 0 - 4 the "<=" would allow "i" to reach the number 5. So something like "movieInfo[i].moviesRating" with "i" being 5 this is beyond the end of the array and not what you want.
Using "<=" in a for loop has the tendency to loop 1 time more than you want. Starting a for loop at zero and checking
i < total
tends to work better, but in this case it is not 100% correct as the outer for loop should not read the last element of the array.
The inner for loop is starting at the wrong place and the "<=" is causing the same problem going past the end of the array.
Look at the line:
if (movieInfo[i].moviesRating < movieInfo[j].moviesRating)
or another way
if (movieInfo[0].moviesRating < movieInfo[0].moviesRating)
Comparing one element to its-self is not what you want. What you do want is
1 2 3
|
if (movieInfo[0].moviesRating < movieInfo[1].moviesRating)
^ ^
i j
|
Looking at this how would you change the for loops to make this work?
At this point I have to ask if writing your own sort code is required? Or could you use "std::sort()" and "std::swap()" from the "algorithm" header file?
I also have to ask if you have learned about "vectors" yet? This would make things much easier over arrays.
Last point. You are reading from a file. It is best to include this file with your code so everyone can see what it looks like and if your code is reading correctly. Also it gives everyone the same information to use.
Andy