You have already learned Why !.eof() inside a loop condition is always wrong. as well as Why is “using namespace std;” considered bad practice? from the comments.
If your professor requires that you use a POA (plain-old array) instead of a container (such as std::vector), then YOU are responsible for all bounds checking to limit your read of elements to no more elements than the array was declared to held, and to keep a valid index of the number of elements read in the event that you read less elements than the container will hold.
So essentially you are being tasked with filling a plain-old C array using C++ iostream for input handling. For starters, don't use Magic-Numbers and don't Hardcode-Filenames. Instead:
#define ARRSZ 10 /* if you need a constant, #define one (or more) */
And the proper prototype for main()
which takes arguments is int main (int argc, char **argv)
(or *argv[]
if you prefer the array-of-pointers equivalent). You can now pass the filename to read from as the first argument to your program and you don't have to recompile your code just to read from another file. To use the argument as your filename to read, you simply need to validate that a sufficient number of arguments were provided on the command line (the name of the program being run is always the first argument, argv[0]
, so the first user-argument is argv[1]
), e.g.
int main (int argc, char **argv) {
if (argc < 2) { /* validate at least one argument given for filename */
std::cerr << "error: insufficient arguments\n"
"usage: " << argv[0] << " in-file\n";
return 1;
}
int ndx = 0, /* index for array */
array[ARRSZ] = {0}; /* array */
std::ifstream fin (argv[1]); /* input file stream */
(note: there is no need for a std::ofstream
file to be opened if you are simply writing to std::cout
)
Now all you need to do is read values from the file into your array while ndx
is less than ARRSZ
. You always want to control your read-loop with the read function being used so that the stream-state can be used to indicate success/failure of your attempted read. Here you have one other limit to protect -- your array bounds. You only want to attempt to read another value from the file if there is room in your array to store the value. Combining both, you can write your input loop as:
/* protect plain-old array bounds && validate integer input */
while (ndx < ARRSZ && fin >> array[ndx])
ndx++; /* increment index on success */
You have now read ndx
elements into your array, so all you need to do is output them both in forward and reverse order. You can do that by looping 0 <= i < ndx
for the forward case and then ndx > i >= 0
in the reverse case, e.g.
std::cout << "forward:\n";
for (int i = 0; i < ndx; i++) /* loop outputting each element */
std::cout << " array[" << i << "]: " << array[i] << '\n';
std::cout << "\nreverse:\n";
for (int i = ndx - 1; i >= 0; i--) /* loop outputting each element */
std::cout << " array[" << i << "]: " << array[i] << '\n';
(note: there is no need to close the file streams -- that occurs automatically as the stream pointer goes out of scope)
Putting it altogether, you could do:
#include <iostream>
#include <fstream>
#define ARRSZ 10 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
if (argc < 2) { /* validate at least one argument given for filename */
std::cerr << "error: insufficient arguments\n"
"usage: " << argv[0] << " in-file\n";
return 1;
}
int ndx = 0, /* index for array */
array[ARRSZ] = {0}; /* array */
std::ifstream fin (argv[1]); /* input file stream */
/* protect plain-old array bounds && validate integer input */
while (ndx < ARRSZ && fin >> array[ndx])
ndx++; /* increment index on success */
std::cout << "forward:\n";
for (int i = 0; i < ndx; i++) /* loop outputting each element */
std::cout << " array[" << i << "]: " << array[i] << '\n';
std::cout << "\nreverse:\n";
for (int i = ndx - 1; i >= 0; i--) /* loop outputting each element */
std::cout << " array[" << i << "]: " << array[i] << '\n';
}
(note: iostream
and fstream
are the only headers required for this limited example. Make a habit of only including the headers required by your source)
Example Input File
Reading 8 integers space separated:
$ cat dat/int8.txt
15815 9999 6607 32552 1479 1769 20868 6058
Example Use/Output
$ ./bin/rdpoafile dat/int8space.txt
forward:
array[0]: 15815
array[1]: 9999
array[2]: 6607
array[3]: 32552
array[4]: 1479
array[5]: 1769
array[6]: 20868
array[7]: 6058
reverse:
array[7]: 6058
array[6]: 20868
array[5]: 1769
array[4]: 1479
array[3]: 32552
array[2]: 6607
array[1]: 9999
array[0]: 15815
Example Input File
Or reading integers separated by '\n'
makes no difference (space
, '\t'
and '\n'
are all whitespace):
$ cat dat/int10.txt
19243
31875
3191
11369
22478
1783
25723
835
12093
6888
Example Use/Output
$ ./bin/rdpoafile dat/int10.txt
forward:
array[0]: 19243
array[1]: 31875
array[2]: 3191
array[3]: 11369
array[4]: 22478
array[5]: 1783
array[6]: 25723
array[7]: 835
array[8]: 12093
array[9]: 6888
reverse:
array[9]: 6888
array[8]: 12093
array[7]: 835
array[6]: 25723
array[5]: 1783
array[4]: 22478
array[3]: 11369
array[2]: 3191
array[1]: 31875
array[0]: 19243
Look things over and let me know if you have further questions.