Learning c++ -- reading numbers from a file - c++

Quick synopsis: I can write the data into the file correctly (I've checked the .txt file and it presents exactly as it should) but all I can read back is the last number inputted. So, if the last quiz grade I input is 85, that's all it will read back. (the studentNumber reads back fine.)
Thanks all! Still learning here ...
while (answer == 1)
{
cout << "What is the student ID?\n";
cin >> studentNumber;
cout << "\n";
cout << "How many quizzes did you take?\n";
cin >> numQuiz;
outputFile << "\n";
outputFile << studentNumber << "\n";
outputFile << "Number of quizzes: " << numQuiz << "\t" "Grades: ";
for (int quiz = 1; quiz <= numQuiz; quiz++)
{
cout << "Please enter the score for quiz " << quiz << "\t";
cin >> score;
total += score;
// cout << "The score is " << score << " .\n";
outputFile << score << "\t"; }
// outputFile << total;
cout << "Do you have a student's grades to input?\nIf yes, type 1. If no, type 0.\n";
cin >> answer;
cin.ignore();
}
outputFile.close();
fstream inputFile;
inputFile.open("grades2.txt");
inputFile >> studentNumber;
cout << studentNumber << "\n";
inputFile >> score;
cout << score << "\n";

You are using the wrong operator to read the data back. Instead of
inputFile << studentNumber;
you need to use
inputFile >> studentNumber;

Related

Reading from text file until EOF infinite loop

I am working at my programming project for school and i came up with idea of "Student Manager Program".
The: name, roll, year, group, course, adress, email, contact, grade are stored as variables in class named Student.
Student's data is written by user keyboard input and saved in studentRecord.txt file, by object.
How can i prevent this while loop to be a not infinite loop. I can't find solution to this problem.
'''
//Displaying Students Record Table
void Student::display() {
system("cls");
ifstream file;
int total = 1;
int x;
cout << "\n-----------------------------Students Record Table-----------------------------" << endl;
file.open("studentRecord.txt");
if (!file) {
cout << "\n\t\t\tNo Data Is Present.";
file.close();
}
else {
file >> name >> roll >> year >> group >> course >> adress >> email >> contact >> grade;
while(!file.eof()) {
cout << "\n\n\t\t\t Student Consecutive Number: " << total++ << endl;
cout << "\t\t\t Student's Name: " << name << endl;
cout << "\t\t\t Student's ID Number: " << roll << endl;
cout << "\t\t\t Student's Year: " << year << endl;
cout << "\t\t\t Student's Group: " << group << endl;
cout << "\t\t\t Student's Course: " << course << endl;
cout << "\t\t\t Student's Adress: " << adress << endl;
cout << "\t\t\t Student's Email: " << email << endl;
cout << "\t\t\t Student's Contact: " << contact << endl;
cout << "\t\t\t Student's Final Grade: " << grade << endl;
file >> name >> roll >> year >> group >> course >> adress >> email >> contact >> grade;
}
if (total == 0) {
cout << "\n\t\t\tNo Data Is Present.";
}
}
do {
cout << "\n\t\t\t If You Want to Back at previous page press 0 and Enter: ";
cin >> x;
if (x == 0) {
file.close();
}
} while (x != 0);
}
'''

Use of getline to read a string with white spaces in a structure

I want to read strings with white spaces into members of a structure. Tried using getline but both the output statements are clubbed with a single cin for both. As per the similar posts here, tried using cin.ignore, but the input is not read into the member of the structure. Pls help. It's a part of my assignment and I'm a beginner in C++. This is how my code looks like:
#include <string.h>
using namespace std;
struct book {
string title, author;
int no_of_pages, year;
float price;
};
int main() {
int N;
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
book b[N];
int x;
for (x = 0; x < N; x++) {
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
// cin.ignore();
cin.ignore(1000, '\n');
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
}
for (x = 0; x < N; x++) {
cout << "\n\n";
cout << "The details of book" << x + 1 << " are:" << endl;
cout << "Title :" << b[x].title << endl;
cout << "Author :" << b[x].author << endl;
cout << "No. of pages :" << b[x].no_of_pages << endl;
cout << "Price :" << b[x].price << endl;
cout << "Publishing year:" << b[x].year << endl;
cout << "---------------------------------------------";
}
return 0;
}
There's no point in using cin.ignore() in between two calls to getline. ignore is used to discard remaining characters after numeric input. So the place to use it is after numeric input and before the next getline. Like this
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
cin.ignore(1000, '\n');
That said I would just read everything using getline, then convert the strings to numbers where needed. That's simpler and cleaner, all you need to know is how to convert a string to an integer, which you can easily research for yourself.
There are two places you should put cin.ignore in your code:
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
// First cin.ignore here
cin.ignore(1000, '\n');
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
// Second cin.ignore here
cin.ignore(1000, '\n');
Besides this I see two more problems in your code:
#include <string> not <string.h>
add #include <iostream>
Why cin.ignore is necessary? User is expected to provide new line ('\n') delimited input. When getline is used, it leaves the input stream in such a state that the next attempt to read input from stream will start at next line. This is not true for operator >>. What int x; cin >> x; does here is it reads only the integer not the new line character present right after the integer. Hence, the next attempt to read will continue within the same line. getline will then find no character before new line and hence will fetch an empty string. To avoid this and to effectively start reading from the next line, cin.ignore is necessary.

ask the user to enter the studentID. Then you will open the text file and search for this ID. (C++)

Struggling really hard with this, I need to enter an ID number thats in a text file and output the associated grades that are on the same line of the text file
This is the code I have, it prints the correct average but it prints the test scores of the next ID numeber
int searchID;
int studentID;
bool found = false;
double exam_1;
double exam_2;
double exam_3;
double average = 0;
cout << "Enter student ID to search in file " <<
fileName << " : ";
//read searchID value
cin >> searchID;
//read data from file until the search id is found
while (fin >> studentID >> exam_1 >> exam_2
>> exam_3 && !found)
{
if (searchID == studentID)
{
average = (exam_1 + exam_2 + exam_3) / 3.0;
found = true;
}
}
//close the file stream,fin
fin.close();
//check if search id is found
if (found)
{
cout << left << setw(10) << "Exam 1" << setw(10) << exam_1 << endl;
cout << left << setw(10) << "Exam 2" << setw(10) << exam_2 << endl;
cout << left << setw(10) << "Exam 3" << setw(10) << exam_3 << endl;
cout << fixed << setprecision(2)
<< "Average : " << average << endl;
}
else
cout << searchID << " student id is not found." << endl;
system("pause");
Your got the loop condition wrong. Lets say one iteration found the ID, found is set to true, then for the next iteration the condition is evaluated:
while (fin >> studentID >> exam_1 >> exam_2 >> exam_3 && !found)
No matter what is the value of found you read the next entry in the file. Change it to
while (!found && fin >> studentID >> exam_1 >> exam_2 >> exam_3)
&& short-circuits, ie when !found is false, the rest of the condition is not evaluated.

Array not initializing properly within a while loop

My issue is that I have set up an array to store totals that were calculated from values read from a file. These stored totals are then added together to find the over all average.
This issue is stemming from a 'cin' at the beginning of the program where the user inputs a number and that number is supposed to drive the program by setting how many times the program loops and how many modules are inside the array. The array does not seem to work properly no matter how much I try.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string StudentGrades;
int studentID;
double quiz1;
double quiz2;
double quiz3;
double quiz4;
int total = 0;
double choice;
ofstream outFile;
double numStud=1;
cout << "Enter student ID number, Quiz 1 Grade, Quiz 2 Grade , Quiz 3 Grade, Quiz 4 Grade" << endl;
outFile.open("StudentGrades.txt");
cout << "How many students would you like to enter?" << endl;
cin >> numStud;
for (int x = 0; x < numStud; x++)
{
cout << "Enter student ID: ";
cin >> studentID;
cout << "Enter quiz grade 1: ";
cin >> quiz1;
//cout << quiz1;
cout << "Enter quiz grade 2: ";
cin >> quiz2;
//cout << quiz2;
cout << "Enter quiz grade 3: ";
cin >> quiz3;
//cout << quiz3;
cout << "Enter quiz grade 4: ";
cin >> quiz4;
//cout << quiz4;
cout << endl;
//outFile.open("StudentGrades.txt");
if (outFile.is_open())
{
cout << "inside if/else outFile" << endl;
//outFile << "File successfully open";
outFile << studentID << " " << quiz1 << " " << quiz2 << " " << quiz3 << " " << quiz4 << endl;
}
else
{
cout << "Error opening file";
}
outFile.close();
/*cout << "Enter 0 for no more students. Enter 1 for more students." << endl;
cin >> choice;
if (choice == 1)
continue;
if (choice == 0)
{
outFile.close();
break;
}*/
}
ifstream inFile;
inFile.open("StudentGrades.txt");
int sTotal;
int total[numStud];
while (inFile >> studentID >> quiz1 >> quiz2 >> quiz3 >> quiz4)
{
//cout << studentID << " " << quiz1 << " " << quiz2 << " " << quiz3 << " " << quiz4 << endl;
total = (quiz1 + quiz2 + quiz3 + quiz4);
sTotal = total[numStud];
double avg = total / 4;
}
system("pause");
return 0;
}
int total[numStud]; is a variable length array and is not standard in C++. If you need an array and you don't know what the size will be then you should use a std::vector. A vector can be used almost exactly as an array can. For example you could would become:
int total;
std::vector<int> studentTotal;
while (inFile >> studentID >> quiz1 >> quiz2 >> quiz3 >> quiz4)
{
//cout << studentID << " " << quiz1 << " " << quiz2 << " " << quiz3 << " " << quiz4 << endl;
studentTotal.push_back(quiz1 + quiz2 + quiz3 + quiz4); // insert into the vector at the end
total += studentTotal.back(); // get last inserted element
}

Why won't this piece of my code write to file

I am developing a C++ banking system.
I am able to get the float, newbal, values correctly and when I try to write to file, there is no data in the file.
else if (x == 2)
{
cout << "You have selected option number 2. Deposit.\n";
cout << "Please enter you account ID: ";
cin >> ID;
file.open("C:\\Users\\Raggulddon\\Desktop\\C++ supplement\\Cust_" + ID + ".dat", ios:: in | ios::out | ios::binary);
if (!file)
{
cout << "Sorry the requested account could not be located.\n";
}
else
{
file >> firstname >> lastname;
cout << endl << firstname << " " << lastname << endl;
cout << "-----------------------------------\n";
string line;
while (getline(file, line))
{
// stringstream the getline for line string in file
istringstream iss(line);
if (iss >> date >> amount)
{
cout << date << "\t\t$" << showpoint << fixed << setprecision(2) << amount << endl;
famount += amount;
}
}
cout << "Your balance is $" << famount << endl;
cout << "How much would you like to deposit today: $";
cin >> amountinput;
float newbal = 0;
newbal = (famount += amountinput);
cout << "\nYour new balance is: $" << newbal << ".\n";
file << date << "\t\t" << newbal; //***This should be writing to file
but it doesn 't.
file.close();
The text file looks like this:
Tony Gaddis
05/24/12 100
05/30/12 300
07/01/12 -300
// Console Output looks like this
Tony Gaddis
05/24/12 100
05/30/12 300
07/01/12 -300
Your balance is: #1
How much wuld you like to deposit: #2
Your new balance is: #1 + #2
write to file
close file.
// exits to main loop::::
How can I make it write to file and save it, and why is this happening.
I tried doing it with ostringstream as well considering how I used istringstream for the input. But it didn't work either:
float newbal=0;
newbal = (famount += amountinput);
ostringstream oss(newbal);
oss << date << "\t\t" << newbal;
I am trying to self teach C++ so any relevant information would be kindly appreciated.
If you want to write a text file, you should not use "ios::binary", when opening the file.