Your basic problem is in function
void readIntFile(ifstream& x, int intArray[], int size, int& length)
You do not set the output variable length
. And you use the wrong index value for your array. Please check.
Additionally there are many other problems in your code.
I will now paste your code, amended with my comments comments, where problems are or where things should be improved.
Please see:
#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
#include<assert.h>
using namespace std; // Should never be used. Always use fully qualified names
const int SIZE = 20; // Please use constexpr
// Do not use C-Style function prototypes. Put main at the bottom
// Do not use C-Style Arrays
// In C++ (C-Style-)Arrays are different. You actually do not pass an array to your function
// but a decyed pointer. You can pass an array by pointer or by reference, but this has a different syntax
void readIntFile(ifstream& x, int intArray[], int size, int &length);
void printValues(int intArray[], int& length);
char getSentinel();
int main()
{
// All variables shall be initialized at the point of defintion
ifstream inputStream; // You should define variables just before you need then
const int size = SIZE; // This is code duplication. And constexpr should be used
string fileName;
int length = 0;
bool isEmpty = false;
int intArray[size]; // C-Style Arrays should not be used. Use std::array or best, std::vector
char sentinel = 'y'; // You could use universal initializer syntax with braced initializer
while (sentinel == 'y' || sentinel == 'Y')
{
cout << "Please enter the name of the file: ";
cin >> fileName;
inputStream.open(fileName); // The constructor can open the file for you
if (inputStream.bad() || inputStream.fail()) // This is too complicated
{
cout << "Error, <" << fileName << "> is Invalid File Name.";
}
if (fileName.empty()) // Check is too late and not necessary
{
isEmpty = true;
}
if (isEmpty == true)
{
cout << "Error <" << fileName << "> has no data.";
}
if (inputStream.good() && isEmpty == false)
{
readIntFile(inputStream, intArray, size, length);
printValues(intArray, length);
inputStream.close(); // Destructor will clsoe the file for you
}
sentinel = getSentinel();
}
return 0;
}
// Not optimal function prototype
void readIntFile(ifstream& x, int intArray[], int size, int& length)
{
// the whole design / logic is very strange
int count = 0;
int arrayLocation = -1; // More then strange. Shows that this is a bad design
int fileInputValue = 0;
x >> fileInputValue;
while (!x.eof()) // Bad or even wrong design
{
count ++; // Wrong. See below. array will be filled with starting with index one
if (count > SIZE)
{
cout << "The file has more than <" << SIZE << "> values." << endl;
break;
}
else
{
arrayLocation ++; // This variable is not used
intArray[count] = fileInputValue;
x >> fileInputValue;
}
}
// Nobody will set the length variable
}
void printValues(int intArray[], int& length)
{
assert(length > 0); // Basically OK, but no necessary here. Cannoz happen
cout << "<" << length << "> values processed from the file. The values are: ";
for (int i=0; i <= length; i++)
{
cout << intArray[i] << ", ";
}
// There is now newline character used anywhere
}
// Very complicated
char getSentinel()
{
char userInput = 'n';
bool inputCheck = false;
cout << "Do you wish to process another file (y/n)?" << endl;
cin >> userInput;
do
{
if (userInput == 'y' || userInput == 'Y' || userInput == 'n' || userInput == 'N')
{
inputCheck = true;
}
else
{
cout << "Invalid response: <" << userInput << ">" << endl;
cout << "Do you wish to process another file (y/n)?" << endl;
cin >> userInput;
}
} while (!inputCheck);
return userInput;
}
Next, I will make your code working, by fixing the biggest problems. I will still follow your programming style.
#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
#include<assert.h>
constexpr int MaxArraySize = 20;
using IntArray = int[MaxArraySize];
void readIntFile(std::ifstream& x, int intArray[], int& length)
{
length = 0;
int value{};
while (x >> value)
{
if (length >= MaxArraySize)
{
std::cout << "The file has more than <" << MaxArraySize << "> values.\n";
break;
}
else
{
intArray[length++] = value;
}
}
}
void printValues(int intArray[], int& length)
{
std::cout << "\n<" << length << "> values processed from the file. The values are: ";
for (int i=0; i < length; i++)
{
std::cout << intArray[i] << ", ";
}
std::cout << "\n\n";
}
bool getSentinel()
{
char userInput{'n'};
bool valid = false;
while (not valid)
{
std::cout << "\n\nDo you wish to process another file (y/n)?\n";
std::cin >> userInput;
if (userInput != 'y' && userInput != 'Y' && userInput != 'n' && userInput != 'N')
{
std::cout << "Invalid response: <" << userInput << ">\n\n";
}
else {
valid = true;
}
}
return ( userInput=='y' || userInput=='Y');
}
int main()
{
int intArray[MaxArraySize];
bool sentinel = true;
while (sentinel)
{
std::cout << "Please enter the name of the file: ";
std::string fileName{};
std::cin >> fileName;
if (fileName.empty())
{
std::cout << "Error <" << fileName << "> has no data.\n\n";
}
else {
std::ifstream inputStream(fileName);
if (!inputStream)
{
std::cout << "Error, <" << fileName << "> is Invalid File Name.\n\n";
}
else
{
int length = 0;
readIntFile(inputStream, intArray, length);
printValues(intArray, length);
}
}
sentinel = getSentinel();
}
return 0;
}
and, in the end, because we are in a C++ site here, I will show (one of many possible) a more advanced C++ solution.
This is just for information and to grab some ideas for the future
#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
#include<vector>
#include<algorithm>
#include<iterator>
#include<initializer_list>
// Some aliases for easier reading and saving typing work
using DataType = int;
using Vector = std::vector<DataType>;
// Define an "in" operator
struct in {
in(const std::initializer_list<char>& il) : ref(il) {}
const std::initializer_list<char>& ref;
};
bool operator,(const char& lhs, const in& rhs) {
return std::find(rhs.ref.begin(), rhs.ref.end(), lhs) != rhs.ref.end();
}
int main() {
// As long as the user wants to read files
for (bool userWantsToContinue{true}; userWantsToContinue;) {
std::cout << "\nPlease enter a valid filename: ";
if (std::string filename{}; std::cin >> filename) {
// Open the file for reading and check, it it is open
if (std::ifstream inputStream{filename}; inputStream) {
// Read all data from the file
Vector data(std::istream_iterator<DataType>(inputStream), {});
// Now show result to user
std::cout << "\nRead values are:\n";
std::copy(data.begin(), data.end(), std::ostream_iterator<DataType>(std::cout, " "));
}
else std::cerr << "\nError: Could not open file '" << filename << "' for reading\n\n";
}
else std::cerr << "\nError: Problem with filename input\n\n";
// Ask, if the user wants to continue
bool validInput{false};
while (not validInput) {
std::cout << "\n\nDo you want to read more files? Please enter 'y' or 'n' ";
if (char selection{}; (std::cin >> selection) && (selection, in{'y','Y','n','N',}) ) {
validInput = true;
userWantsToContinue = (selection, in{'y','Y'});
}
else {
std::cout << "\n\nInvalid input, please retry\n\n";
}
}
}
return 0;
}