(c++) reading from a text file - c++

I made this program that asks users to enter the grade of some students, determine whether they pass or fail and then determine how many pass and how many fail the exam. Here's my code:
#include <iostream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade;
int final_grade;
int student = 5;
while (student > 0)
{
cout << "Enter mid-term grade: ";
cin >> mid_grade;
cout << "Enter final grade: ";
cin >> final_grade;
double total_grade = (double)mid_grade*3/10 + (double)final_grade*7/10;;
cout << "The total grade is: " << total_grade << endl;
student --;
if (mid_grade < 4 || final_grade < 4 || total_grade < 10)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}
cout << passing << " student passed" << endl;
cout << failing << " student failed" << endl;
return 0;
}
what I want to do now is to tell my program to read the mid-term and the final grade in a text file I made then calculate the total grade (like I did in the above code), then show the grades on the screen, determine who pass and fail the exam and the total number of students who pass/fail the exam.
Here's what my text file looks like:
Mid-term Final
8 5
9 6
10 11
15 17
9 20
11 19

Alright so this should help. I put some notes. You need to create a text file in the same directory /src called grades.txt
should look like this
10 9 8 7 4 3 4 5 5 9
You will need to change things. But this should give you a good starting point or where you should be going. Hope this helps.
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade = 0; //Always initilize your variables!!!
int final_grade = 0;
int student = 5;
//Create a variable to open the file
ifstream inFile; inFile.open("src\\grades.txt");
while (student > 0)
{
cout << "Enter mid-term grade: ";
inFile >> mid_grade;
cout << mid_grade << endl;
cout << "Enter final grade: ";
inFile >> final_grade;
cout << final_grade << endl;
cout << "student number" << student << endl; //Notice it goes backwards you have to fix it.
double total_grade = ((double)mid_grade*3)/10 + ((double)final_grade*7/10);
cout << "The total grade is: " << total_grade << endl;
student --;
cout << endl;
if (total_grade < 7)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}`enter code here`
cout << passing << " student penter code hereassed" << endl;
cout << failing << " student failed" << endl;
return 0;
}

I'd read the file, skip the 1st line, then read the rest, line by line, using stringtokenizer to get the two values to work with.

Related

New to C++, modules and switch menu

I am working on a project that involves creating a menu screen, and integrating three programs into one that can be selectively launched from the menu screen.
I thought making individual programs first before piecing them together with switch case and functions would be easy (I don't know class/objects). I keep running into a brick wall and a host of syntax/logical errors, so I deleted everything and now I'm back to square one-- with three distinct programs. This is very daunting-- how do proceed? :/
#include <iostream>
using namespace std;
int main ()
{
int x;
cout << "Enter the amount of money you have ";
cin >> x;
if (x >= 20) {
cout << "You can buy Comic Book $1 or Sports Journal $3 or Science Book $15 or Third Volume Series $20";
} else if (x >= 15 && x < 20) {
cout << "You can buy Comic Book $1 or Sports Journal $3 or Science book $15";
} else if (x >= 3 && x < 15) {
cout << "You can buy Comic Book $1 or Sports Journal $3";
} else if (x >= 1 && x < 3) {
cout << "You can buy Comic Book $1";
} else if (x <= 0) {
cout << "You cannot afford anything";
}
return 0;
}
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
int numclass; //number of classes
int numStudents; //number of students
int numTests; // Number of tests per student
double sectiontotal; //Accumulator for Class total scores
double total; // Accumulator for total scores
double average; //Average test score
double totalaverage = 0;
ofstream outfile;
outfile.open("Gradesinfo.txt");
// Set up numeric output formatting.
cout << fixed << showpoint << setprecision(1);
// Get the number of students.
cout << "This program gives average of test scores per student, per class, and for the whole institution for upto 2 students in upto 2 different classes in 3 subjects\n";
// Determine each student's average score.
cout << "Enter the number of classes";
cin >> numclass;
cout << "Enter the number of students per class";
cin >> numStudents;
cout << "Enter the number of tests";
cin >> numTests;
for (int section = 1; section <= numclass; section++) {
sectiontotal = 0; //Initialize class accumulator
totalaverage = 0;
for (int student = 1; student <= numStudents; student++) {
total = 0; // Initialize the accumulator.
for (int test = 1; test <= numTests; test++) {
double score;
cout << "Enter score " << test << " for ";
cout << "student " << student << ": ";
cin >> score;
if (score >= 0 && score <= 100) {
total += score;
} else {
cout << "Enter value from 1 - 100" << endl;
test = test - 1;
}
}
average = total / numTests;
totalaverage += average;
cout << "The average score for student " << student;
cout << " is " << average << ".\n\n";
outfile << "The average score for student " << student;
outfile << " is " << average << ".\n\n";
}
cout << "The total average for class " << section << " is: " << totalaverage / numStudents << endl;
outfile << "The total average for class " << section << " is: " << totalaverage / numStudents << endl;
sectiontotal += totalaverage;
}
cout << "The total average for the institution is: " << sectiontotal / numclass;
outfile << "The total average for the institution is: " << sectiontotal / numclass;
outfile.close();
return 0;
}
#include<cstdlib>
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream instream;
ofstream outstream;
instream.open("Grades.txt");
if (instream.fail()) {
cout << "The input file failed to open\n";
exit(1);
}
int next, largest, smallest;
largest = 0;
smallest = 0;
while (instream >> next) {
if (largest < next) {
largest = next;
} else {
smallest = next;
}
}
cout << "The highest grade is: " << largest << endl;
instream.close();
system("pause");
return 0;
}
I think you are shooting yourself on the foot. go 1 step after the other, please do take this as reference:
create a main file as entry point for the app, note the prototype and implementation of the functions printA and printB
#include <iostream>
using namespace std;
void printA();
void printB();
int main()
{
int x = 1;
cout << "Enter the option:\n";
while (cin >> x)
{
if (x <= 0)
{
break;
}
switch (x) {
case 1:
printA();
break;
case 2:
printB();
break;
default:
cout << "Invalid";
}
}
return 0;
}
void printB()
{
cout << "B";
}
void printA()
{
cout << "A";
}
create a new file fooA.cpp and paste there the implemented function printA
do the same for the printB in another file.
remove those implementations from main.cpp
you are done!

Reading numbers from text and outputting average

So I am working to read text from a file (line by line) and output the ID, average of 4 grades following the ID, and the letter grade. So the letter grade for any average grade of 50 or above is S, anything below 50 is a U, and 2 excused classes results in the letter grade I. (No S or U if more than or equal to 2 excused).
So lets say file has the numbers:
42 50 51 57 52
48 90 -1 60 -1
40 46 -1 59 45
47 50 -1 49 50
The output should look something like this:
ID=42 Avg=52.5 Grade=S
ID=48 Excused=2 Grade=I
ID=40 Avg=50.0 Grade=S
ID=47 Avg=49.7 Grade=U
Number of Grades of Type
S U I
2 1 1
This is the output I am receiving from my code
It is reading all the numbers, but i need it to read the first number as ID and following 4 numbers as grade.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream in;
ofstream results;
string filename;
char grade;
int S = 0, U = 0, I = 0, i = 0, ID, excused = 0, avg;
double allscores = 0;
cout << "Enter the name of the file that has the scores of students: " << endl;
cin >> filename;
cout << "Enter the number of scores for each student: " << endl;
cin >> ID;
in.open(filename);
results.open("results.txt");
if (in)
{
while (in >> ID)
{
int first = 0
for (i = 0; i<=4; i++)
{
if (first == -1)
excused++;
else
allscores += first;
}
if (first > 4)
{
avg = allscores / (4 - excused);
if (avg >= 50.0)
{
grade = 'S';
S++;
cout << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
else
{
grade = 'U';
U++;
cout << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
}
else
{
grade = 'I';
I++;
cout << "ID=" << ID << " Excused=" << excused << " Grade =" << grade << endl;
}
}
}
else
{
cout << "Couldn't open file\n";
}
cout << "Number of Grades of Type" << endl;
cout << "S " << "U " << "I" << endl;
cout << S << " " << U << " " << I << endl;
in.close();
results.close();
system("pause");
return 0;
}
Your variable int first=0 is not being assigned any value other than 0 in your code so the statement if(first>4) will always be false and result the output your are getting.
You can do something like this:
while (in >> ID)//this is supposed to get the ID of each student, in order for that to happen you need to read all the 4 scores inside this loop before coming here and reading the next ID,otherwise everything will read as an ID
{
int first = 0
excused=0;//you need to reset excused on every iteration
allscores=0;//you need to reset allscore on every iteration
for (i = 0; i<4; i++)
{//here you need to get all the 4 scores
in>>first;//get each score in first
if (first == -1)
excused++;
else
allscores += first;
}
if(excused<2)//instead of if(first>4)
...//do your calculation for average score
else
...//set the grade to 'I'...
}
Here is my final solution:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream in;
ofstream results;
string filename;
char grade;
int S = 0, U = 0, I = 0, i = 0, ID, excused = 0, avg;
double allscores = 0;
cout << "Enter the name of the file that has the scores of students: " << endl;
cin >> filename;
cout << "Enter the number of scores for each student: " << endl;
cin >> ID;
in.open(filename);
results.open("results.txt");
if (in)
{
while (in >> ID)
{
int first = 0;
excused = 0;
allscores = 0;
for (i = 0; i < 4; i++)
{
in >> first;
if (first == -1)
excused++;
else
allscores += first;
}
if (excused < 2)
{
avg = allscores / (4 - excused);
if (avg >= 50.0)
{
grade = 'S';
S++;
results << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
else
{
grade = 'U';
U++;
results << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
}
else
{
grade = 'I';
I++;
results << "ID=" << ID << " Excused=" << excused << " Grade =" << grade << endl;
}
}
}
else
{
cout << "Couldn't open file\n";
}
results << "Number of Grades of Type" << endl;
results << "S " << "U " << "I" << endl;
results << S << " " << U << " " << I << endl;
in.close();
results.close();
system("pause");
return 0;
}
After the code I have it output to a file named "results".
Thanks for the help. I guess my while loop was the biggest mistake.
Especially not adding in the in >> first portion.

Confusing C++ Assignment

I'm a freshman college CS student, and I can't seem to figure this problem out. It basically wants me to ask the user for the amount of students in a particular class, and then continuously loop asking for the students names. After all that is done, I have to find out which name that was entered will be first, alphabetically, and which name will be last, alphabetically.
My code so far does everything up until I have to sort through the names, as well as displaying the names incorrectly. It only displays the latest name entered, not both names at once.
#include <iostream>
#include <string>
using namespace std;
int main () {
int studentCount;
string studentName;
cout << "Hello fellow educator!" << endl;
cout << "I will be helping you with your line-up for today." << endl;
cout << "Please enter the number of students in your class: ";
cin >> studentCount;
cout << endl;
cout << endl;
if (studentCount < 1 || studentCount > 25) {
cout << "Please try again." << endl;
cout << "Try putting in a number between 1 and 25." << endl;
cout << endl;
}
for (int count = 1; count <= studentCount; count++) {
cout << "Please enter a student's name: ";
cin >> studentName;
}
cout << "the names are " << studentName; // Just testing the string
return 0;
}
As you collect names, Store the names in a data structure.If you keep adding all names to a single string, then, it can be stored as one concatenated string but we want different names(strings).
So, Lets take vector as our datastructure.
int main () {
int studentCount;
string studentName;
vector<string> attendanceBook;
for (int count = 1; count <= studentCount; count++) {
cout << "Please enter a student's name: ";
studentName.clear();
cin >> studentName;
attendanceBook.push_back(studentName);
}
std::sort(attendanceBook.begin(),attendanceBook.end());
cout<<"First: "<<name.front<<endl<<"Last: "<<name.back();
So this is the completed code, after hours of work, and it runs and does everything properly. It's simple, I know, but to a college freshman only having been exposed to the surface of Java, this is complicated to me. :) I knew there was a way of doing this without vectors or arrays.. Thanks to everyone who tried their best to help me. I'll be sure to come back in the future.
#include <iostream>
#include <string>
using namespace std;
int main () {
int studentCount;
string studentNames;
string first;
string last;
cout << "Hello fellow educator!" << endl;
cout << "I will be helping you with your line-up for today." << endl;
cout << "Please enter the number of students in your class: ";
cin >> studentCount;
cout << endl;
cout << endl;
while (studentCount < 1 || studentCount > 25) {
cout << "Please try again." << endl;
cout << "Try putting in a number between 1 and 25: ";
cin >> studentCount;
}
for (int count = 0; count < studentCount; count++) {
cout << "Please enter the name for student number " << count + 1 << ":";
cin >> studentNames;
if (count == 1) {
first = studentNames;
last = studentNames;
}
else {
if (studentNames < first) {
first = studentNames;
}
else if (studentNames > last) {
last = studentNames;
}
}
}
cout << "The first student in line is " << first << "." << endl;
cout << "The last student in line is " << last << "." << endl;
return 0;
}
First, you need to make an array of string instead of a single string to avoid overwriting.
After that, sort them lexicographically and print them.
EDIT:
Have a look at the code given below:
#include <iostream>
#include <string>
#include <algorithm> /* Used to sort the string lexicographically */
#define LIMIT 50 /* I'm considering that you are not providing more than 50
names at once to a program*/
using namespace std;
int main () {
int studentCount; /* Count number of the students */
string studentName[LIMIT]; /* Array of string */
cin >> studentCount; /* Input number of student */
/* Keep on asking until the correct value of studentCount is not provided */
while (studentCount < 1 || studentCount > 25) {
cout << "Please try again." << endl;
cout << "Try putting in a number between 1 and 25." << endl;
cin >> studentCount;
}
cout <<"Please enter a student's name: ";
for (int count = 0; count < studentCount; count++) {
cin >> studentName[count]; /* I started the count value from 0 to n-1
because the index of an array starts from 0 */
}
/* Now, time to sort the array of string lexicographically */
sort(studentName, studentName+studentCount);
/* Print the names of the student */
cout << "Names of the students : " << endl;
for(int i=0; i< studentCount; i++) {
cout << studentName[i] << endl;
}
return 0;
}
This code will keep on asking until correct value of studentCount is not received. You can even change the upper limit of the program by changing the value of LIMIT from 50 to something else you may need.

C++ Address Book Array and Textfile

Sorry for the lack of previous explanation to my school's assignment. Here's what I'm working with and what I have / think I have to do.
I have the basic structure for populating the address book inside an array, however, the logic behind populating a text file is a bit beyond my knowledge. I've researched a few examples, however, the implementation is a bit tricky due to my novice programming ability.
I've gone through some code that looks relevant in regard to my requirements:
ifstream input("addressbook.txt");
ofstream out("addressbook.txt");
For ifstream, I believe implementing this into the voidAddBook::AddEntry() would work, though I've tried it and the code failed to compile, for multiple reasons.
For ostream, I'm lost and unsure as to how I can implement this correctly. I understand basic file input and output into a text file, however, this method is a bit more advanced and hence why I'm resorting to stackoverflow's guidance.
#include <iostream>
#include <string.h> //Required to use string compare
using namespace std;
class AddBook{
public:
AddBook()
{
count=0;
}
void AddEntry();
void DispAll();
void DispEntry(int i); // Displays one entry
void SearchLast();
int Menu();
struct EntryStruct
{
char FirstName[15];
char LastName[15];
char Birthday[15];
char PhoneNum[15];
char Email[15];
};
EntryStruct entries[100];
int count;
};
void AddBook::AddEntry()
{
cout << "Enter First Name: ";
cin >> entries[count].FirstName;
cout << "Enter Last Name: ";
cin >> entries[count].LastName;
cout << "Enter Date of Birth: ";
cin >> entries[count].Birthday;
cout << "Enter Phone Number: ";
cin >> entries[count].PhoneNum;
cout << "Enter Email: ";
cin >> entries[count].Email;
++count;
}
void AddBook::DispEntry(int i)
{
cout << "First name : " << entries[i].FirstName << endl;
cout << "Last name : " << entries[i].LastName << endl;
cout << "Date of birth : " << entries[i].Birthday << endl;
cout << "Phone number : " << entries[i].PhoneNum << endl;
cout << "Email: " << entries[i].Email << endl;
}
void AddBook::DispAll()
{
cout << "Number of entries : " << count << endl;
for(int i = 0;i < count;++i)
DispEntry(i);
}
void AddBook::SearchLast()
{
char lastname[32];
cout << "Enter last name : ";
cin >> lastname;
for(int i = 0;i < count;++i)
{
if(strcmp(lastname, entries[i].LastName) == 0)
{
cout << "Found ";
DispEntry(i);
cout << endl;
}
}
}
AddBook AddressBook;
int Menu()
{
int num;
bool BoolQuit = false;
while(BoolQuit == false)
{
cout << "Address Book Menu" << endl;
cout << "(1) Add A New Contact" << endl;
cout << "(2) Search By Last Name" << endl;
cout << "(3) Show Complete List" << endl;
cout << "(4) Exit And Save" << endl;
cout << endl;
cout << "Please enter your selection (1-4) and press enter: ";
cin >> num;
cout << endl;
if (num == 1)
AddressBook.AddEntry();
else if (num == 2)
AddressBook.SearchLast();
else if (num == 3)
AddressBook.DispAll();
else if (num == 4)
BoolQuit = true;
else
cout << "Please enter a number (1-4) and press enter: " << endl;
cout << endl;
}
return 0;
}
int main (){
Menu();
return 0;
}
As it currently stands, I'm still stuck. Here's where I believe I should start:
cout << "Please enter your selection (1-4) and press enter: ";
cin >> num;
cout << endl;
if (num == 1)
AddressBook.AddEntry();
else if (num == 2)
AddressBook.SearchLast();
else if (num == 3)
AddressBook.DispAll();
else if (num == 4)
BoolQuit = true;
//save first name
//save last name
//save dob
//save phone number
//save email
//exit
else
cout << "Please enter a number (1-4) and press enter: " << endl;
cout << endl;
}
Somehow, during menu option 4 the array should dump the data into a .txt file and arrange it in a way that it can be easily imported upon reloading the program. I'm a little confused as to how I can store the array data from each character array into a .txt file.
Well first, if the input is coming from the file input, then instead of doing cin >> x you would have to do input >> x. If it's coming from standard input (the keyboard), then you can use cin.
Also, your else if statement should be something like this:
while (true)
{
// ...
else if (num == 4)
{
for (int i = 0; i < AddressBook.count; ++i)
{
AddBook::EntryStruct data = AddressBook.entries[i];
out << data.FirstName << " " << data.LastName
<< std::endl
<< data.Birthday << std::endl
<< data.PhoneNum << std::endl
<< data.Email;
}
}
break;
}

C++ Output Errors

The output for this program, thanks to you guys, is fixed. Except for the studentNumber. I read the comment that I never set a value to it and that confused me.
void process_file(ifstream& input)
{
int thisStudent = 0;
StudentRecord student = StudentRecord();
while (thisStudent++ < CLASS_SIZE)
{
student.input(input, thisStudent);
student.computeGrade();
student.output();
}
}
would this not set studentNumber equal to 0 then add +1 every time it runs through the loop.
// Author:
// Assignment 8
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
ofstream outputfile("output.txt");
const int MAX_FILE_NAME = 35;
const int CLASS_SIZE = 5;
class StudentRecord
{
public:
void input( ifstream& input,int studentid);
void computeGrade();
void output();
private:
int studentNumber;
double exam1;
double exam2;
double exam3;
double exam4;
double average;
char grade;
};
void open_input(ifstream& input, char name[]);
void process_file(ifstream& input);
int main()
{ char again;
char file_name[MAX_FILE_NAME + 1];
ifstream input_numbers;
cout << "This program can calculate the exam average and grade for\n"
<< "each student.\n" << endl;
system("pause");
do
{
system("cls");
open_input(input_numbers, file_name);
process_file(input_numbers);
input_numbers.close();
cout << "\nDo you want to process another file (Y/N)? ";
cin >> again;
cin.ignore(256, '\n');
} while ( again == 'y' || again == 'Y');
cout << "\nEnd of Program!" << endl;
outputfile << "\n\nThanks for using GradeCalc!\f";
outputfile.close();
return 0;
}
void process_file(ifstream& input)
{
int thisStudent = 0;
StudentRecord student = StudentRecord();
while (thisStudent++ < CLASS_SIZE)
{
student.input(input, thisStudent);
student.computeGrade();
student.output();
}
}
void open_input(ifstream& input, char name[])
{ int count = 0;
do
{ count++;
if (count != 1)
{ cout << "\n\aInvalid file name or file does not exist. Please try again."
<< endl;
}
cout << "\nEnter the input file name (maximum of " << MAX_FILE_NAME
<< " characters please)\n:> ";
cin.get(name, MAX_FILE_NAME + 1);
cin.ignore(256, '\n');
input.clear();
input.open(name,ios_base::in);
} while (input.fail() );
}
void StudentRecord::input(ifstream& input, int studentid)
{
input >> exam1 >> exam2 >> exam3 >> exam4;
}
void StudentRecord::computeGrade()
{
average = (exam1 + exam2 + exam3 + exam4) / 4 ;
if (average >= 90)
grade = 'A';
else if (average >= 80)
grade = 'B';
else if (average >= 70)
grade = 'C';
else if (average >= 60)
grade = 'D';
else if (average < 60)
grade = 'F';
}
void StudentRecord::output()
{
cout << "\n\nThe record for student number:" << setw(8) << studentNumber << endl;
cout << "The exam grades are:" << setw(8) << exam1 << exam2 << exam3 << exam4 << endl;
cout << "The numeric average is:" << setw(8) << average << endl;
cout << "and the letter grade assigned is:" << setw(8) << grade << endl;
}
Well, studentNumber is garbage because you never put a value in it. So it just has whatever happened to already be in memory at that location.
The exam grades print out wrong because commas in C++ don't do what you think they do, and that's also why adding an endl; to it gives you an error.
The formatting I'm going to let you work out for yourself. You should consider reading up on output or at least doing some trial and error.
One of the errors is that instead of this:
cout << "The exam grades are:" << setw(8) << exam1, exam2, exam3, exam4;
I think you mean this:
cout << "The exam grades are:" << setw(8) << exam1 << exam2 << exam3 << exam4 << endl;
CLASS_SIZE is defined as 5, so this loop:
while (thisStudent++ < CLASS_SIZE)
will iterate 6 times.
Also
cout << "The exam grades are:" << setw(8) << exam1, exam2, exam3, exam4;
This outputs exam1, and then evaluates and does nothing with the rest of the variables.
70 80 90 95 95 85 90 80 75 85 70 80 55 85 50 70 45 50 40 35
does it have the spaces? If yes, you need to ignore them. input >> exam1 >> exam2 >> exam3 >> exam4; would load space into one of the exam variables.
-- edit for MooingDuck --
#include <iostream>
#include <sstream>
using namespace std;
int main() {
cout << "main() ENTRY" << endl;
stringstream s1(ios_base::in | ios_base::out),
s2(ios_base::in | ios_base::out);
int i = -1;
s1 << "111 222";
s1 >> i; cout << i << endl;
s1 >> i; cout << i << endl;
s2 << "111 222";
s2 >> noskipws;
s2 >> i; cout << i << endl;
s2 >> i; cout << i << endl;
return 0;
}
Output:
main() ENTRY
111
222
111
0