If I split the code into two separate programs it works like I want it to (separating3 part#1 where I create the file, and part #2 where I try to access the file as a user); but as soon as I put the code into a single program (see below), I am unable to use the getline() method to collect input from the standard input; the program just plows through to the end without stopping to collect user input at the point where the getline method is in the source code.
I read a bunch of answered questions and tried to no avail the following:
#include <string>
outFile.clear();
inFile.clear();
The purpose of the program is to create a text file, then get 2 grades from a 'teacher' and put them into the text file. The second part asks the user to enter a path to a file; then the code provides an average of the grades in the file. The problem is that the code below never stops to allow the user to enter the path of the file.
#include <iostream>
#include <fstream> //file steam for access to objects that work with files
#include <cstdlib>
//using namespace std;
int main()
{
//****************PART #1 - CREATE A FILE & ADD DATA *************************************************
std::cout << "Part #1 - create file & put data into it.\n" << std::endl;
//create an object called "outFile" of type ofstream (output file stream)
// arg #1 - path and file name
// arg #2 - constant that represents how we want to work with file (output stream in this case)
std::ofstream outFile("/home/creator/Desktop/creation.txt", std::ios::out);
//get user to enter 5 numbers:
int userGrade;
for(int i = 0; i < 2; i++)
{
std::cout << "Enter grade number " << (i+1) << ": ";
std::cin >> userGrade; //collect a grade from the user
outFile << userGrade << std::endl; //write data to file (each number on it's own line)
}
outFile.close();//close the stream
std::cout << "All is well and good - file is created and data is populated" << std::endl;
//****************PART #2 - READ & MUNIPILATE DATA FROM FILE*****************************************
std::cout << "\nNext, lets read the data from the file we created." << std::endl;
std::cout << "please enter the path to the file: (ex: /home/creator/Desktop/creation.txt)" << std::endl;
std::string fileName; //the path to the file we want to read.
std::getline(std::cin, fileName);//<<< THIS IS MY QUESTION/PROBLEM
std::ifstream inFile(fileName.c_str(), std::ios::in);
if(!inFile)
{
std::cout << "File not found!" << std::endl;
exit(1);
}
double grade = 0;//this holds the data we retrieve from file
double total = 0; //get the sum of all the grades as a total
double average = 0; //get the average of all the grades
int numberOfGrades = 0; //number of grade values in file
//retreive and munipilate the data from the file.
while(!inFile.eof())
{
inFile >> grade;
total = total + grade;
numberOfGrades++;
std::cout << grade << std::endl;
}
average = total / numberOfGrades;
std::cout << "The average of the grades in the file is: " << average << std::endl;
inFile.close();
return 0;
}
Image of the output as the code just plows through:
The problem is that the previous input loop leaves the last newline in the input buffer, which the next call to std::getline
reads as an empty line.
This is easily fixed by ignoring the rest of the line after you read the grades.
From the example in the linked reference:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
On an unrelated note, do not use while (!inFile.eof()) { ... }
, it will not work as you expect it to. Instead, in your case, you should do while (inFile >> grade) { ... }
.