Print out book titles sorted alphabetically.

Hello, I don't know where to go from here, I am having a mental block. I will leave the instructions for the code and also what I already have done. I need help creating the for loop. Please check the code, I just want to make sure I am doing good, and also to notice if is something else I am missing, Thank you


#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>

using namespace std;


/*
separate function to print the required info on the screen:

This function should receive the vector as a parameter.
*/

void myFunction(vector<string> books){
// For loop to iterate your vector
// Use a range-based for loop or iterator to print the titles.
for(auto book: books){
// print each book
}

}








int main(){


ifstream inFile;
inFile.open("Books.txt");

//Check for Error


while(inFile.fail()){
string name;
cerr<<"Error opening File" << endl;
cout << "Provide a valid fileName.txt please." << endl;
cin >> name;
inFile.open(name);
}

vector<string> booksName;
string line;
while(getline(inFile, line)){
stringstream lineStream(line);
string title;
getline(lineStream, title, ',');
booksName.push_back(title);
}
sort(booksName.begin(),booksName.end());

//call function here
myFunction(booksName);
}



/*File processing:
Program should try to open a file using a default file path first, then check if it was successful, if not, ask the user for a different file name/path and try again until it succeeds. Do not try to process a file that you could not open. Remember to close the file when done reading.
Read each line from the file using getline: getline (ifstream input, string line)
Store the book titles in a vector (not an array!).
To separate the title from the line, you can make the line a stream:
stringstream lineStream(line);
then use getline again to take the title: getline(lineStream, title, ',');
To add values to a vector, use function push_back.
Sort the data using the sort function
Refer to cplusplus qsort (Links to an external site.) to learn how to use sort.
Define a separate function to print the required info on the screen:
This function should receive the vector as a parameter.
Use a range-based for loop or iterator to print the titles.
Do not use global variables! Do not use goto!
Document your source code following the guidelines at:
Lab Documentation Guidelines
Attach the output of your program as a comment at the end of your source code.
Download the input file to test lab 1 herePreview the document.

The Output:

The output should have titles only, one title per line and they should be in alphabetical order*/.




Consider (not tried):

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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

void myFunction(const vector<string>& books) {
	for (const auto& book : books)
		cout << book << '\n';
}

int main()
{
	ifstream inFile("Books.txt");

	while (!inFile) {
		string name;

		cerr << "Error opening File\n";
		cout << "Provide a valid fileName.txt please.\n";
		cin >> name;
		inFile.open(name);
	}

	vector<string> booksName;

	for (string line, title; getline(inFile, line); ) {
		istringstream lineStream(line);

		getline(lineStream, title, ',');
		booksName.push_back(title);
	}

	sort(booksName.begin(), booksName.end());

	//call function here
	myFunction(booksName);
}

Hello Lucyzzz,

While I look into your program.


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.


Andy

P.S. It would help if you include the input file or a good sample. Better for everyone to be able to use the same file.
Last edited on
Hello Lucyzzz,

I have always felt that knowing what you did wrong first helps you to understand what you need to fix and it may also help to understand the code that seeplus has posted.

To start with: void myFunction(vector<string> books). First this needs a better name. Something like "PrintBooks", "PrintTitles" or something else that describes what the function does.

Next is the parameter. Passing variables like "bool", "char", "int" and "double" by value means that the compiler is making a copy of the value and creating a local variable for the function. For these simple types that is not a problem.

When you pass more complicated variables like "std::string" and "std::vector" these are better passed by reference so that the program does not have to take the time or waste space making a copy. It will use what was defined somewhere else.

Making the parameter "const" is kind of 50/50. The function only uses the vector, but the "const" is a safety measure to make sure it is not changed in the function. This way the compiler will complain if you do something that tries to change a value in the vector. Other times you leave the "const" off because you want to change the value(s) in a vector.

All that is left here is the "cout" to print the titles.

In "main" I started out with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
    const std::string PATH{ "./" };  // <--- A default path, i.e., the current working directory.
    //const std::string PATH{ "C:/.../.../" };

    ifstream inFile(PATH + "Books.txt");
    //inFile.open("Books.txt");

    //Check for Error
    while (inFile.fail())  // <--- The more often preferred method "while (!inFile)". Will check more than just the "fail" bit.
    {
        string name;

        cerr << "Error opening File\n";
        cout << "Provide a valid fileName.txt please.\n";

        // <--- You might want to provide available file name(s) and or path.

        cin >> name;

        inFile.open(PATH + name);
    }

Since the directions mention a path I added lines 3 and 4. You could copy line 4 as many times as you need and set up a different path switching the comments as needed.

You will find that line 6 is the more often used way of using the overloaded ctor of the streams to define the variable used and open the file at the same time. Should this fail to open the file the ".open" in the while loop will work since the file stream variable has already been defined.

The next while loop I think will work except that I have no idea what the input file looks like. So I do not know if it will actually work.

Also with out the input file I do not see any reason for the string stream unless you need the practice.

The call to "std::sort" looks OK, but could be a problem if you try to sort titles with upper and lower case letters. Some titles may not sort properly. Just something to keep in mind.

Understanding this might help to understand what seeplus did.

Andy
Hello Andy,

Thank you for your help. This is the first time that I try posting something, I apologize for not using the proper format, I will follow your advice for a future post.

Hello Seeplus,

Thank you so much for your help. Now I know what I was missing. I don't have so much experience with vectors, so I will try doing other similar programs. Have a great day!.
Topic archived. No new replies allowed.