Read text file into a function.

I am having trouble with ifstream and reading from a file. Essentially, I would like to "open" the file, read the data into an array, display the information, then "close" the file. Eventually I will have to create a struct of an array ... blah blah. Baby steps.

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
/// Function Code

void bookFunction(ifstream bookFile)
{
    ///open files

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

    //verify file is open and read to array??

    if(!inputB)
    {
        cout << "File not found" <<endl;
    }
    else
    {
        cout << "Books" << endl;

        int bookInventory;
        inputB >> bookInventory;

        // arrayType arrayName[bookInventory];

        //build array
        for(int i=0; i<bookInventory; i++)
        {
            inputB >> //arrayName[i].structVariable1 >> arrayName[i].structVariable2 >> ... ;
        }

        //display array
        for (int i=0; i<bookInventory; i++)
        {
            cout << //function (arrayName[i].structVariable) << endl;
        }
    }


    ///output

    cout << "Books" << endl;
    cout << "1. Name: " << endl;
    cout << "2. Hardcover: " << endl; // 1 for yes, 0 for no
    cout << "3. Number of pages: " <<endl;
    cout << "4. Price: " << endl;
    cout << "5. Total Inventory: " << endl;
    cout << "6. Date Published: " << endl; //month:day:year

    ///close files

    inputB.close("Book.txt");

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

/* Text for function, read like:
16 = total inventory
bookTitle hardcoverYesNo(1 = hardcover, 0 = not) noOfPages price datePublished*/

16
PrideandPrejudice 1 209 10.99 10 04:01:2010
ToKillaMockingbird 0 276 10.99 3 03:10:2013
TheGreatGatsby 1 257 7.99 3 06:21:2000
JaneEyre 1 294 10.99 8 06:01:2005
TheCatcherintheRye 1 171 10.99 2 07:06:2006
LittleWomen 0 354 10.99 3 02:26:2008
HuckleberryFin 1 269 7.99 2 02:27:2015
MobyDick 0 278 10.99 1 07:13:2012
AliceinWonderland 1 494 10.99 7 08:17:2015
LordoftheFlies 1 133 10.99 1 06:06:2016
AnimalFarm 1 119 7.99 5 03:22:2015
GreatExpectations 0 287 10.99 9 06:13:2013
1984 0 275 10.99 8 04:14:2017
GreatExpectations 1 360 10.99 7 07:23:2016
Frakenstein 0 146 10.99 3 03:20:2010
TheScarletLetter 1 248 10.99 5 02:28:2014
looks like a great start, what exactly is the trouble?
bookfile (passed into the function) seems totally useless since you use a local ifstream.
23 if uncommented would not be legal in standard c++. the size of arrays needs to be known at compile time as a constant. Is this where you ran into problems?

This will read the file into a vector of struct and then display the contents. Note that there is an unexplained field in the file. Also note that book title can't contain a space. Also you don't really need the first line of the file (no of items) as this will be determined. It's only used here to check.

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

struct Book {
	std::string title;
	bool hardcover {};
	unsigned pages {};
	double price {};
	unsigned unknown {};
	std::string date;
};

std::istream& operator>>(std::istream& ifs, Book& book)
{
	return (ifs >> book.title >> book.hardcover >> book.pages >> book.price >> book.unknown >> book.date);
}

std::ostream& operator<<(std::ostream& ofs, const Book& bk)
{
	return (ofs << std::setw(20) << std::left << bk.title << std::right << std::setw(7) << std::boolalpha << bk.hardcover << std::setw(7) << bk.pages << std::setw(7) << std::fixed << std::setprecision(2) << bk.price << "  " << bk.date);
}

int main()
{
	std::ifstream ifs("books.txt");

	if (!ifs)
		return (std::cout << "Cannot open file\n"), 1;

	unsigned noItems {};

	ifs >> noItems;

	std::vector<Book> books;

	for (Book book; ifs >> book; books.emplace_back(book));

	if (noItems != books.size())
		return (std::cout << "Problem reading file\n"), 2;

	for (const auto& bk : books)
		std::cout << bk << '\n';
}



PrideandPrejudice      true    209  10.99  04:01:2010
ToKillaMockingbird    false    276  10.99  03:10:2013
TheGreatGatsby         true    257   7.99  06:21:2000
JaneEyre               true    294  10.99  06:01:2005
TheCatcherintheRye     true    171  10.99  07:06:2006
LittleWomen           false    354  10.99  02:26:2008
HuckleberryFin         true    269   7.99  02:27:2015
MobyDick              false    278  10.99  07:13:2012
AliceinWonderland      true    494  10.99  08:17:2015
LordoftheFlies         true    133  10.99  06:06:2016
AnimalFarm             true    119   7.99  03:22:2015
GreatExpectations     false    287  10.99  06:13:2013
1984                  false    275  10.99  04:14:2017
GreatExpectations      true    360  10.99  07:23:2016
Frakenstein           false    146  10.99  03:20:2010
TheScarletLetter       true    248  10.99  02:28:2014


PS Are you using VS2019? If yes, L23 can be simplified using C++20 std::format()

For C++20 format, insert at top #include <format> and replace L23 with

 
return ofs << std::format("{: <20}{: >7}{: >7}{: >7.2f}{:>12}", bk.title, bk.hardcover, bk.pages, bk.price, bk.date);

Last edited on
Thank you,

My comments are notes to work with later.
This is the updated function, (before I read your replies)

The main will be only variables and function calls.
I created a header file for structs and a source file for functions. I think that the professor wants to see individualized reports for each line of the txt files.
I just realized that the current code will only print one txt file line to the screen, I think that I will need to incorporate a for loop(?) to read all of the lines and generate a "profile" for each.

The 1 and 0 for hardcover is like bin. 1 = yes, 0 = no.

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

void bookFunction(ifstream bookFile)
{
    ///open files

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

    //verify file is open and read to array

    if(!inputB)
    {
        cout << "File not found" <<endl;
    }
    else
    {
        cout << "Books file opened" << endl << endl;

        int bookList;
        string title;
        int hardcover;
        int noOfPages;
        double price;
        int totalInventory;
        string datePublished;

        inputB >> bookList >> title >> hardcover >> noOfPages >> price >> totalInventory >> datePublished;

        // arrayType arrayName[bookInventory];

        //build array
        for(int i=0; i<bookList; i++)
        {
            inputB >> //arrayName[i].structVariable1 >> arrayName[i].structVariable2 >> ... ;
        }

        //display array
        for (int i=0; i<bookList; i++)
        {
            cout << //function (arrayName[i].structVariable) << endl;
        }
    }


    ///output

    cout << "Books" << endl;
    cout << "----------" << endl;
    cout << "1. Name: " << endl;
    cout << "2. Hardcover: " << endl; // 1 for yes, 0 for no
    cout << "3. Number of pages: " <<endl;
    cout << "4. Price: " << endl;
    cout << "5. Total Inventory: " << endl;
    cout << "6. Date Published: " << endl; //month:day:year

    ///close files

    inputB.close("Book.txt");

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
16 /// bookList, like titles in inventory
PrideandPrejudice 1 209 10.99 10 04:01:2010
ToKillaMockingbird 0 276 10.99 3 03:10:2013
TheGreatGatsby 1 257 7.99 3 06:21:2000
JaneEyre 1 294 10.99 8 06:01:2005
TheCatcherintheRye 1 171 10.99 2 07:06:2006
LittleWomen 0 354 10.99 3 02:26:2008
HuckleberryFin 1 269 7.99 2 02:27:2015
MobyDick 0 278 10.99 1 07:13:2012
AliceinWonderland 1 494 10.99 7 08:17:2015
LordoftheFlies 1 133 10.99 1 06:06:2016
AnimalFarm 1 119 7.99 5 03:22:2015
GreatExpectations 0 287 10.99 9 06:13:2013
1984 0 275 10.99 8 04:14:2017
GreatExpectations 1 360 10.99 7 07:23:2016
Frakenstein 0 146 10.99 3 03:20:2010
TheScarletLetter 1 248 10.99 5 02:28:2014
I am using CodeBlocks V20.03, I think.

And we haven't gotten to vectors yet. I will need to create an array of struct instead.
Last edited on
Hello Fayezilla,

Have a look at the comments 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
int bookFunction(std::ifstream bookFile) // <--- Unless you are creating a new variable "fstreams" are usually passed by reference.
{
    ///open files

    std::ifstream inputB;
    inputB.open("Books.txt");

    //verify file is open and read to array??

    if (!inputB)
    {
        return std::cout << "File \"Books.txt\" not found\n", 1;  // <--- If you reach here you should leave the function.
    }

    std::cout << "Books\n";

    int bookInventory;
    inputB >> bookInventory;

    // arrayType arrayName[bookInventory];

    //build array
    for (int i = 0; i < bookInventory; i++)
    {
        //inputB >> //arrayName[i].structVariable1 >> arrayName[i].structVariable2 >> ... ;
    }

    //display array
    for (int i = 0; i < bookInventory; i++)
    {
        //std::cout << //function (arrayName[i].structVariable) << '\n';
    }


    ///output

    std::cout << 
        "Books\n"
        "1. Name: " << aVariable << "\n"
        "2. Hardcover: \n" // 1 for yes, 0 for no
        "3. Number of pages: \n"
        "4. Price: \n"
        "5. Total Inventory: \n"
        "6. Date Published: \n"; //month:day:year

    ///close files

    inputB.close(/*"Book.txt"*/);  // <--- Function takes no arguments. Not necessary as the dtor will close
                                   // the file stream when the function looses scope. OK if you leave it.

    return 0;
}

Line 39 is what I think you want to do. I just do not have enough information to know what to put there. Also do not have enough of the code to compile and test.

I changed the function to return an "int" and would call the function as:
1
2
3
4
int response{};

if (response = bookFunction(???))
    return response;

If the function call fails to open the file and the returned value is something other than (0)zero you will leave the program. If the returned value is (0)zero you bypass the if statement and continue with the program.

Not sure what to do about the for loops yet.

Andy
I will need to create an array of struct instead.


OK.

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
#include <fstream>
#include <iostream>
#include <string>
#include <iomanip>
//#include <format>

struct Book {
	std::string title;
	bool hardcover {};
	unsigned pages {};
	double price {};
	unsigned unknown {};
	std::string date;
};

std::istream& operator>>(std::istream& ifs, Book& book)
{
	return (ifs >> book.title >> book.hardcover >> book.pages >> book.price >> book.unknown >> book.date);
}

std::ostream& operator<<(std::ostream& ofs, const Book& bk)
{
	return (ofs << std::setw(20) << std::left << bk.title << std::right << std::setw(7) << std::boolalpha << bk.hardcover << std::setw(7) << bk.pages << std::setw(7) << std::fixed << std::setprecision(2) << bk.price << "  " << bk.date);
	//return ofs << std::format("{: <20}{: >7}{: >7}{: >7.2f}{:>12}", bk.title, bk.hardcover, bk.pages, bk.price, bk.date);
}

int main()
{
	constexpr size_t MaxBooks {100};

	std::ifstream ifs("books.txt");

	if (!ifs)
		return (std::cout << "Cannot open file\n"), 1;

	unsigned noItems {};

	ifs >> noItems;

	Book books[MaxBooks] {};
	size_t NoBooks {};

	for (Book book; NoBooks < MaxBooks && ifs >> book; books[NoBooks++] = book);

	if (noItems != NoBooks)
		return (std::cout << "Problem reading file\n"), 2;

	for (size_t i = 0; i < noItems; ++i)
		std::cout << books[i] << '\n';
}

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.
The rest from part 1.

The "while" loop can be replaced with a "for" loop, but I tend to like the while loop.

In line 6 I used the "std::boolalpha" to change the "false" and "true" in the file to (0)zero and (1) to store in the bool variable in the struct.

Lines 13 and 14 are optional. To me a date is separated by a (/) not a (:). Keep if you want or delete if the (:) is what you want to use.

After the last formatted input into "sDatePublished" you need the ignore to get rid of the (\n) before the next "std::getline".

The if statement is just in case the number on line 1 of the file is not what is actually read from the file. It is always a possibility that something could be added or deleted from the file and the number on line 1 is not changed. This should not be a problem with a for loop if done correctly.

The only thing left is what I did in "main".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    int response{}, numRecords{};
    BOOKS books;  // <--- Not knowing what you did , this is an array of structs. Works for now.

    if (response = bookFunction(numRecords, books))
        return response;

    std::cout << std::fixed << std::setprecision(2);  // <--- Only needs done once. Stays in affect until changed.

    DisplayArray(books);

    return 0;  // <--- Not required, but makes a good break point for testing.
}

Almost forgot:
1
2
3
4
5
6
7
8
9
10
11
12
struct Book
{
    std::string sName;
    bool sHardCover{};
    int sNumOfPages{};
    double sPrice{};
    std::string sDatePublished;
};

constexpr unsigned int MAXSIZE{ 20 };

using BOOKS = Book[MAXSIZE];

Not knowing what you did I created a quick struct to work with.

Line 12 creates a user variable "BOOKS" and says it is an array of structs of type Book. This has the advantage of passing the array to functions by reference. Otherwise the array would degrade to a pointer. This way you can see the whole array in a function.

There is something to think about for awhile.

Andy
Last edited on
To me a date is separated by a (/) not a (:). Keep if you want or delete if the (:) is what you want to use.

to me one of the top 10 pure awesome of 64 bit computers is the date.
dates now fit as
20210604152530 format. you still have room for a few (4 digits) of subseconds if you want too.
(today at 3:25 and 30 seconds)
you can totally manage dates this way 100% without all the gibberish code from back when.
you can also use the epoch thing (1970 magic year) for some tasks and fit that with subseconds into a 64 bit. But I have always thought that was a poor approach.
Last edited on
Thank you every one.
I think that I was over complicating the outputs., I'll attach a sample output.
This is the code that I have so far. I will go through and work with the code every one has provided.

Thank you again! oh,yeah...I'm not allowed global variables

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

struct book ///<- this is in a header file
{
    int bookList;
    string title;
    bool hardcover;
    int noOfPages;
    double price;
    int totalInventory;
    string datePublished;
};

void bookFunction(ifstream& bookFile, book bookArray[], int bookList) ///<-this is in a 'source' file
{
    ///open files

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

    ///verify file is open and read to array

    if(!inputB)
    {
        cout << "File not found" <<endl;
    }
    else
    {
        cout << "Books file opened" << endl << endl;

        /*              -> saved for notes
        int bookList;
        string title;
        int hardcover;
        int noOfPages;
        double price;
        int totalInventory;
        string datePublished;
        */

        inputB >> book.bookList >> book.title >> book.hardcover >>
                  book.noOfPages >> book.price >> book.totalInventory >> book.datePublished;
        /// *error: expected primary expression before '.' token


        ///build array
        for(int i=0; i < bookList; i++)
        {
            book bookArray[i];
            inputB >> bookArray[i].title >> bookArray[i].hardcover >> bookArray[i].noOfPages >>
                      bookArray[i].price >> bookArray[i].totalInventory >> bookArray[i].datePublished;
        }

        /* -> commented out, possible delete
        ///display array
        for (int i=0; i < book.bookList; i++)
        {
            cout << //function (arrayName[i].structVariable) << endl;
        }
        */

        ///Print array
        cout << "-" << endl; /// 76 dashes??
        cout << "Books" << endl;
        cout << "-" << endl; /// last verse same as the first

        ///output for each book in listing

        cout << "Title               | Hardcover | No. of Pages | Inventory | Date Published " << endl;
        cout << "----------------------------------------------------------------------------" << endl;
        cout << book.title << setw(20) << "|" << book.hardcover << setw(11) << "|" << book.noOfPages << setw(14) << "|"
             << book.totalInventory << setw(11) << "|" << book.datePublished << setw(16) << endl;

             ///setw to align with column titles...

    }

    ///close files

    inputB.close();

}

using namespace std; ///<- this is copied from the 'main'

int main()
{
    ifstream inputF; /// <- do these need to be here if defined in inputFunctions.cpp??
    ifstream inputA;
    ifstream inputFA;
    ifstream inputB;

    userMenu(category); /// *error: 'category' not declared in this scope

/*

    furnitureFunction();
    artFunction();
    fabricFunction();

*/

    bookFunction(bookFile); /// *error: 'bookfile' not declared in this scope

    return 0;
}



/// for '16' titles this is the input

16
PrideandPrejudice 1 209 10.99 10 04:01:2010
ToKillaMockingbird 0 276 10.99 3 03:10:2013
TheGreatGatsby 1 257 7.99 3 06:21:2000
JaneEyre 1 294 10.99 8 06:01:2005
TheCatcherintheRye 1 171 10.99 2 07:06:2006
LittleWomen 0 354 10.99 3 02:26:2008
HuckleberryFin 1 269 7.99 2 02:27:2015
MobyDick 0 278 10.99 1 07:13:2012
AliceinWonderland 1 494 10.99 7 08:17:2015
LordoftheFlies 1 133 10.99 1 06:06:2016
AnimalFarm 1 119 7.99 5 03:22:2015
GreatExpectations 0 287 10.99 9 06:13:2013
1984 0 275 10.99 8 04:14:2017
GreatExpectations 1 360 10.99 7 07:23:2016
Frakenstein 0 146 10.99 3 03:20:2010
TheScarletLetter 1 248 10.99 5 02:28:2014




---------------------------------------------------------------------------------------------------------
                                                               Books
---------------------------------------------------------------------------------------------------------
title                  | Hardcover | # of Pages | Price | total Inventory | date Published
---------------------------------------------------------------------------------------------------------
PrideandPrejudice   |     Yes       |      209        |10.99|           10           |   04:01:2010
....

/// something like this. I have multiple functions and files to compile, but I'm working with this one function first.


Last edited on
Do arrays have to be built in the main or can I build them within each function?
Hello Fayezilla,

You can define arrays in a function, but at the closing brace of the function the variables defined in the function are lost.

Better to define what you want to keep in "main" and pass them to the functions that need them.

Andy
I think I got it!!

How do I make a line, like "======" for 50 or more spaces?
I was using setfill('='), but then it was just filling everything
Hello Fayezilla,

"setfill" will work and it would look something like:
std::setfill('=') << std::swtw(50) << ' ' << std::setfill(' ') << '\n';

Remember when you change "setfil" you have to change it back when you are done with it.

Another choice is the fill ctor of "std::string": std::string(50,'=') You could use this in a "cout" line or give it a name and create a string.

Something I did:
1
2
3
4
std::cout <<
    "Title               | Hardcover | No. of Pages | Inventory | Date Published\n"
    //"----------------------------------------------------------------------------\n"
    << std::string(75, '-') << '\n';


Produces the output of:

Title               | Hardcover | No. of Pages | Inventory | Date Published
---------------------------------------------------------------------------

I find using the "std::string" much easier most of the time.

Andy

Edit:
Last edited on
@Fayezilla. Based upon your code, perhaps:

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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

struct Book {
	std::string title;
	bool hardcover {};
	int noOfPages {};
	double price {};
	int totalInventory {};
	std::string datePublished;
};

constexpr size_t maxBook {100};

void bookRead(Book bookArray[], size_t& bookList)
{
	std::ifstream inputB("Books.txt");

	if (!inputB) {
		std::cout << "File not found\n";
		return;
	}

	//std::cout << "Books file opened\n\n";

	inputB >> bookList;

	for (size_t i = 0; i < maxBook && i < bookList; ++i)
			inputB >> bookArray[i].title >> bookArray[i].hardcover >> bookArray[i].noOfPages >>
				bookArray[i].price >> bookArray[i].totalInventory >> bookArray[i].datePublished;
}

void bookDisplay(const Book bookArray[], size_t bookList)
{
	std::cout << std::string(77, '-') << '\n';
	std::cout << std::setw(35) << ' '<< "Books\n";
	std::cout <<  std::string(77, '-') << '\n';

	std::cout << "Title                 | Hardcover | No. of Pages | Inventory | Date Published\n";
	std::cout << std::string(77, '-') << '\n';

	for (size_t b = 0; b < bookList; ++b)
		std::cout << std::left << std::setw(22) << bookArray[b].title << "|   " << std::boolalpha << std::setw(8) << bookArray[b].hardcover << "|     "
			<< std::setw(6) << bookArray[b].noOfPages << std::right << std::setw(4) << "|" << std::setw(6) << bookArray[b].totalInventory
			<< std::setw(6) << "|" << std::setw(13) << bookArray[b].datePublished << '\n';
}

int main()
{
	Book bookarray[maxBook] {};
	size_t booklist {};

	bookRead(bookarray, booklist);
	bookDisplay(bookarray, booklist);
}



-----------------------------------------------------------------------------
                                   Books
-----------------------------------------------------------------------------
Title                 | Hardcover | No. of Pages | Inventory | Date Published
-----------------------------------------------------------------------------
PrideandPrejudice     |   true    |     209      |    10     |   04:01:2010
ToKillaMockingbird    |   false   |     276      |     3     |   03:10:2013
TheGreatGatsby        |   true    |     257      |     3     |   06:21:2000
JaneEyre              |   true    |     294      |     8     |   06:01:2005
TheCatcherintheRye    |   true    |     171      |     2     |   07:06:2006
LittleWomen           |   false   |     354      |     3     |   02:26:2008
HuckleberryFin        |   true    |     269      |     2     |   02:27:2015
MobyDick              |   false   |     278      |     1     |   07:13:2012
AliceinWonderland     |   true    |     494      |     7     |   08:17:2015
LordoftheFlies        |   true    |     133      |     1     |   06:06:2016
AnimalFarm            |   true    |     119      |     5     |   03:22:2015
GreatExpectations     |   false   |     287      |     9     |   06:13:2013
1984                  |   false   |     275      |     8     |   04:14:2017
GreatExpectations     |   true    |     360      |     7     |   07:23:2016
Frakenstein           |   false   |     146      |     3     |   03:20:2010
TheScarletLetter      |   true    |     248      |     5     |   02:28:2014


Oh for std::format() in C++20!
Last edited on
Topic archived. No new replies allowed.