Hello Fayezilla,
The first question I have to ask is if the input file is something that you have to use or can you change it?
I changed the input file to this if you can use it:
16
Pride and Prejudice, true 209 10.99 04:01:2010
To Kill a Mockingbird, false 276 10.99 03:10:2013
The Great Gatsby, true 257 7.99 06:21:2000
Jane Eyre, true 294 10.99 06:01:2005
The Catcher in the Rye, true 171 10.99 07:06:2006
Little Women, false 354 10.99 02:26:2008
Huckleberry Fin, true 269 7.99 02:27:2015
Moby Dick, false 278 10.99 07:13:2012
Alice in Wonderland, true 494 10.99 08:17:2015
Lord of the Flies, true 133 10.99 06:06:2016
Animal Farm, true 119 7.99 03:22:2015
Great Expectations, false 287 10.99 06:13:2013
1984, false 275 10.99 04:14:2017
Great Expectations, true 360 10.99 07:23:2016
Frakenstein, false 146 10.99 03:20:2010
The Scarlet Letter, true 248 10.99 02:28:2014
|
The blank line at the top and bottom are not in the file.
Adding the comma and the spaces in the title allows you to use "std::getline()" to read the title. Somewhere I have some code that would read the title with spaces and stop at the next field. First I will have to find it and then test it.
I finished the final tweaks on the program this morning.
The for loop in the "bookFunction", or how about "ReadFile" which describes what it does better, that displays the array should be a function of its own. Thinking ahead you could write the function to display just 1 book then use a for loop elsewhere to display the whole array or say from a search function just display what matches.
The function I wrote has 2 possible forms of output. You can choose whichever 1 you like.
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
|
void DisplayArray(const BOOKS& books)
{
constexpr std::streamsize WIDTH{ 19 };
//std::cout << "\n Books\n";
std::cout << '\n' << std::string(17, ' ') << "Books\n";
std::cout << std::string(40, '-') << '\n';
for (int idx = 0; idx < 3/*numRecords*/; idx++)
{
///output
//std::cout <<
// "\n"
// " 1. Name: " << books[idx].sName << "\n"
// " 2. Hardcover: " << (books[idx].sHardCover ? "yes" : "no") << "\n" // 1 for yes, 0 for no
// " 3. Number of pages: " << books[idx].sNumOfPages << "\n"
// " 4. Price: " << books[idx].sPrice << "\n"
// " 5. Total Inventory: \n"
// " 6. Date Published: " << books[idx].sDatePublished << "\n"; //month:day:year
std::cout <<
"\n"
<< std::setw(WIDTH) << "Name: " << books[idx].sName << "\n"
<< std::setw(WIDTH) << "Hardcover: " << (books[idx].sHardCover ? "yes" : "no") << "\n" // 1 for yes, 0 for no
<< std::setw(WIDTH) << "Number of pages: " << books[idx].sNumOfPages << "\n"
<< std::setw(WIDTH) << "Price: " << books[idx].sPrice << "\n"
<< std::setw(WIDTH) << "Total Inventory: " << 100 << "\n"
<< std::setw(WIDTH) << "Date Published: " << books[idx].sDatePublished << "\n"; //month:day:year
}
}
|
These are the 2 possible outputs:
Books
1. Name: Pride and Prejudice
2. Hardcover: yes
3. Number of pages: 209
4. Price: 10.99
5. Total Inventory:
6. Date Published: 04/01/2010
1. Name: To Kill a Mockingbird
2. Hardcover: no
3. Number of pages: 276
4. Price: 10.99
5. Total Inventory:
6. Date Published: 03/10/2013
1. Name: The Great Gatsby
2. Hardcover: yes
3. Number of pages: 257
4. Price: 7.99
5. Total Inventory:
6. Date Published: 06/21/2000
Books
----------------------------------------
Name: Pride and Prejudice
Hardcover: yes
Number of pages: 209
Price: 10.99
Total Inventory: 100
Date Published: 04/01/2010
Name: To Kill a Mockingbird
Hardcover: no
Number of pages: 276
Price: 10.99
Total Inventory: 100
Date Published: 03/10/2013
Name: The Great Gatsby
Hardcover: yes
Number of pages: 257
Price: 7.99
Total Inventory: 100
Date Published: 06/21/2000
|
You can switch the comments on lines 5, 6 and 7 for whichever 1 you like. Same goes for inside the for loop.
Removing the for loop and moving lines 5, 6 and 7 you can display just 1 element of the array. You would also have to change the parameters to accept 1 element of the array, or 1 Book struct.
Lines 15 and 24 use the ternary operator to change the (0)zero and (1) stored in the bool variable into "yes" and "no".
This is where the fun comes in. I started off with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int bookFunction(int& numRecords, BOOKS& books)
{
///open files
const std::string inFileName{ "Books.txt" };
std::ifstream inFile(inFileName);
//inFile.open("Books.txt");
//verify file is open and read to array??
if (!inFile)
{
return std::cerr << "\n File \"" << inFileName << "\" not found\n", 1; // <--- If you reach here you should leave the function.
//return std::cerr << "\n File " << std::quoted(inFileName) << " not found\n", 1; // <--- Requires the "<iomanip>" header file.
}
|
Since you should be including the "iomanip" header file for "setprecision" the "std::quoted" function is something you need to be told about because I doubt that it has been covered in class or in a book yet.
Once the file stream is open and ready you will first likely do:
1 2 3 4
|
inFile >> numRecords;
inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
// <--- Or you could use "inFile.ignore()" to eat the (\n) left in the buffer before the "getline".
|
You have 2 choices for getting rid of the (\n) left in the buffer. the 1st is considered the more portable way that any compiler should be able to use. The second will just ignore 1 character, should be the (\n), and then finish.
Now before actually reading the file you need to answer the question. Do I create an array larger than what I would need or do I create a dynamic array based on the first line of the file?
Not knowing what the whole program should I have to consider functions like "Add", "Delete" and "Search" may be needed. The "Add" function would make a dynamic array more difficult to use.
After reading the first line I came up with this:
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
|
int idx{};
//build array
while (idx < MAXSIZE && std::getline(inFile, books[idx].sName, ','))
{
inFile >> std::boolalpha >> books[idx].sHardCover
>> books[idx].sNumOfPages
>> books[idx].sPrice
>> books[idx].sDatePublished;
inFile.ignore();
books[idx].sDatePublished.replace(2, 1, 1, '/');
books[idx++].sDatePublished.replace(5, 1, 1, '/');
}
if (numRecords != idx)
{
std::cerr <<
"\n"
" There is a discrepancy in the file!\n"
" The number of records stated in the file does not match what was read.\n";
numRecords = idx;
}
|
End of part 1.
Sorry about that I ran out of space.