Hello:

I need help with a project.

I have to read an input file that contains data for 17 students. This is how they are: first ID, then first name, then last name, then 10 test scores.

For this data, I have to read it and process it to send it to a new file that only contains:

the last name, a comma, the first name, the ten scores, and the average for them followed by a letter grade.

However, the names have to be in alphabetical order, and it has to be formatted.

This is the code I have now:

It outputs the last name, a comma, first name, scores, average and letter grade.

However, it doesn't put the names in order neither makes them look formatted.

Any ideas?

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;


int main(int argc, char *argv[])
{
 ifstream infile;
 int ID, score[10];
 float ave, sum=0;
 string firstn, lastn, fullname;
 infile.open ("c:\\students.txt");
 while (infile>>ID>>firstn>>lastn)  // read file
 {
       fullname= lastn + "," +firstn;   // combine last 
 cout.setf(ios::fixed);                    // and 1st name
 cout.setf(ios::showpoint);      
    
 cout<<fullname<<" ";  // Outputs fullname


 for (int n=0; n<10; n++)  // processes scores
 { infile>>score[n];
   
 cout<<score[n]<<" ";  // outputs scores
 sum+=score[n];          // sums scores
 }
 ave=sum/10;        // Processes average
 cout.precision(3);
  cout<<ave<<" ";    // Outputs average
  if (ave>=90)
  {cout<<"A";         // Processes letter grades and
  }                         // Outputs it
  else       
  {    if (ave>=80)
       {cout<<"B";
       }
       else
       {    if(ave>=70)
           {cout<<"C";
           }
           else
           {   if(ave>=60)
               {cout<<"D";
               }
               else
               {cout<<"F";
               }
           }
       }
  }
 cout<<endl;
 sum=0;             // resets sum to 0 for new student
}
 
 
 
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

<< moderator edit: added [code][/code] tags >>

For example:

The output for let's say two students would be:


Cannon, Scott 70 75 78 88 83 85 79 91 88 90 82.7 B
Espinola, Angelica 97 98 89 88 90 92 95 100 92 88 99.1 A


In alphabetical order and name to the left, and scores, average and letter grade to the right!

I've got the names to the left, but I need to sort them and move scores and average to the right all aligned!


this thing doesn't let me put them justified but at least it is similar!

I've working with this, and I have already solved the formatting problem, my only problem left is how to put the names in order!

This is how I changed it a little, I just included some width and precision functions, as well as left and right justifiers.

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;


int main(int argc, char *argv[])
{
 ifstream infile;
 int ID, score[10];
 float ave, sum=0;
 string firstn, lastn, fullname;
 infile.open ("c:\\students.txt");
 while (infile>>ID>>firstn>>lastn)
 {
 fullname= lastn + "," +firstn;
 cout.setf(ios::fixed);
 cout.setf(ios::showpoint);      
 
  cout.precision(3);
cout << showpoint;
cout.width(20);   
 cout<<left<<fullname<<" ";


 for (int n=0; n<10; n++)
 { infile>>score[n];
 cout.precision(3);
cout << showpoint;
cout.width(3);
cout <<right<<score[n]<<" ";
 sum+=score[n];
 }
 ave=sum/10;
 cout.precision(1);
  cout<<ave<<" ";
  if (ave>=90)
  {cout.precision(1);
  cout << showpoint;
  cout.width(2);
  cout<<right<<"A";
  }
  else
  {    if (ave>=80)
       {cout.precision(1);
       cout << showpoint;
       cout.width(2);
       cout<<right<<"B";
       }
       else
       {    if(ave>=70)
           {cout.precision(1);
           cout << showpoint;
           cout.width(2);
           cout<<"C";
           }
           else
           {   if(ave>=60)
               {cout.precision(1);
               cout << showpoint;
               cout.width(2);
               cout<<"D";
               }
               else
               {cout.precision(1);
               cout << showpoint;
               cout.width(2);
               cout<<"F";
               }
           }
       }
  }
 cout<<endl;
 sum=0;
}
 
 
 
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

<< moderator edit: added [code][/code] tags >>

The sorting you can do in many ways. One way could be putting all the data in let's say a class and then sort the vector of objects with ssort(), qsort() or whatever function you want. Other way could be putting the unsorted lines in a temp file, taking the first letter of every line and comparing the first letter from the next line with it (Tip: after the first letter, which is at position 0 in the file every next letter will be after a '\n'). If the corresponding condition is true you can swap the lines and go on. There are other ways probably better ones, this is what comes to me now.

The formatting you can do by creating an imaginary "name field" for the names. When you get them from the file and create the fullname you can check it's length and save it as a temporary. Consequtive checks can give you the size of the longest name. When writing the temp output file you can check the name of the student before streaming it to the file and add to it (if necessary) the number of white spaces it needs to reach the name with the max size, i.e. int bla = longest_name - fullname.size(); and add 'bla' blanks to fullname. Then you can continue with copying the scores. Since I don't know the inbuilt C++ libraries too good I can't offer you a more subtle way to do the formatting, but this should work.

You are going to need to store the information as you read it in, do the sort and then write it back out. Can't write each line as you read it in AND sort at same time. my c/c++ is a little rusty but you want something like the following. Was in a little bit of a hurry and was doing this in notepad, so there might be some mismatched brackets, but that should give you an idea

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;


int main(int argc, char *argv[])
{
ifstream infile;
int IDarray[17], scorearray[17][10];
int count = 0, ID;
float ave[17], sum=0;
string firstn, lastn, fullname[17];
string tempname;
int tempint;

// get all the data
infile.open ("c:\\students.txt");
while (infile>>ID>>firstn>>lastn) // read file
{
fullname[count]= lastn + "," +firstn; // combine last 
IDarray[count] = id;
for (int n=0; n<10; n++) // processes scores
{ infile>>score[count][n];
}
count++;
}

// sort it

for (int n=0; n<17; n++){
	for (int m=n+1; m<17; m++)
	{
	
		if(fullname[m] comes before [fullname[n])// sorry, can't give you this exactly will have to do pseudocode
		{
			tempname = fullname[m];
			fullname[m] = fullname[n];
			fullname[n] = tempname;
			for(int i = 0; i < 10; i++)
			{
				tempint = score[n][i];
				score[n][i] = score[m][i];
				score[m][i] = tempint;
			}
		}
	}
}

// now that it is sorted by name, print it out
cout.setf(ios::fixed); // and 1st name
cout.setf(ios::showpoint); 
for (int i = 0; i < 17; i++){
	sum = 0;
	for (int j = 0; j < 10; j++)
	{
		sum += score[i][j];
	}
	ave=sum/10; // Processes average
	cout<<fullname<<" "; // Outputs fullname
	cout<<score[n]<<" "; // outputs scores
	cout.precision(3);
	cout<<ave<<" "; // Outputs average
	if (ave>=90)
	{
		cout<<"A"; // Processes letter grades and
	} // Outputs it
else 
{ if (ave>=80)
{cout<<"B";
}
else
{ if(ave>=70)
{cout<<"C";
}
else
{ if(ave>=60)
{cout<<"D";
}
else
{cout<<"F";
}
}
}
}
cout<<endl;

}








system("PAUSE");
return EXIT_SUCCESS;
}

I am still working on this problem, but I cannot find a way to finish it without mixing up all the scores and the names.

Is there a way to sort the names without mixing the scores with anyone else's scores.

I can't use pointers because I do not know them yet.

Nor, classes!


Please, any help is really apprecciated, I am really confused.

The code sent to me is kind of confusing because it makes me loose track of what it is doing!

Can anyone explain it to me, I find it difficult to understand two dimensional arrays!

Doing this without using struct/classes will be tedious. You could have an array of firstnames only, an array of last names only, an array of middle names only, an array for each persons first exam grades, an array for each persons second exam grades, ..., an array for each persons grade average, and an array for each letter grade. A given index in a given array has the information for the same person. Therefore, if you have to rearrange the order of the names after loading all the file data, to keep everything correlated by index you could rearrange the order for each of the other arrays in the same manner. So, for example, if you are using bubble sort to sort the array of last names and you end up swapping LastName with LastName
Then you will need to swap:
FirstName with FirstName;
Exam1 with Exam1;
Exam2 with Exam2;
.
.
.
Exam10 with Exam10;
AveNumResult with AveNumResult;
and, finally
LetterGrade with LetterGrade;
etc.

After setting all that up just once, I can assure you, you will appreciate what struct/classes can do for you when you learn about them.

Since you don't know pointers then you won't be able to use lists, so if you try to sort with insertion rather than after completely reading the file you will need to be able to shift all contents coming after desired insertion location in all arrays to make room for the new entry. Having said that however, it might be easier than sorting post insertion. Your call.

In the end, however, I suspect the exercise is either to get you used to working with arrays

Do you mean that I can open the first file and once opened I can insert the ID, first name, last name, 10 scores, for each of the 17 students in different arrays, and after that sort them alphabetically?

So, after sorting calculate average and letter grade?

Or, first calculate average and letter grades and then sort the names!

That is what confuses me because I do not know if first I have to read it and process them and then sort them or viceversa!

Now, i have them all formatted and average processed, and letter grade too.

But, i did not put names into arrays, so I do not know if i have to redo the whole project, or if I can work from what I have!

So, after sorting calculate average and letter grade?

Or, first calculate average and letter grades and then sort the names!

you could do it either way. Personally, I would sort first and then figure the grade and the average. If you do it the other way, just two extra things that have to be swapped when you do the sort

But tell me something, to sort the names, is it possible to do it without arrays or not.

The thing is that I am not sure if I can use a string array that contains both the first, and last name, and then how to change them and include a comma in the middle!

I guess you could find a way to do it without arrays, but I don't know why you would want to. What function are you using to compare the names to see which one should be first

These are the specifications the teacher gave us to include in the project!
I hope you can see now what I am supposed to do so it is easier for me to start correctly!


Write a program to compute grades for a course. The records are in a file. Each line has ID, space, lastname, space, firstname, space, 10 scores.

the output has to be formatted, no ID, lastname, comma, firstname, 10 scores, average, letter Grade.

List has to be alphabetized in ascending order. Use at least one function that has file streams as all or some of its arguments.

Hints;

use an array for students name and other for test scores.
instead of sorting both arrays, sort index array instead.
keep track of number of students
total length of name with comma and space is less than 20 characters.

If you are going to sort data you need to hold it in some sort of container and then spit it all back out once you have completed the work you need to do. If you read from file and spit stuff out to the screen for each student as the data is read from the file you can't sort the data. What container type you use depends a lot on what container you know. Since you don't know about struct/class, then you can't use that container. Since you don't know pointers, then you can't use lists. The only container left is arrays. Therefore you will need to put the data you read from file into arrays and sort it as you insert or sort everything at once after you've read everything in from file. Then, when everything is sorted you can print out the sorted data stored the array(s) to the screen. Whether you calculate the average and the assign the grade as you are reading from file, or after you sort the raw data and then analyze it before printing it out (you don't even have to sort the average/grade if you don't want to) is up to you. You can store the first and last name as a single string if you want, or as separate strings, up to you. If you store the entire name as a single string, and you want to sort on the last name, then the last name needs to be the first word in the string. It's better to separate the first name and last name if you are going to sort alphabetically, but you don't have to if you don't know how.

For the last name and first name is it possible to say?

string firstname, lastname;
int score[10];

then while readign the file:


while (infile>>ID)
{
infile>>firstname;
infile>>lasntame;
for (int n=0; n<10; n++)
{ infile>>score[n];
}
}

or should I use a for loop to enter the first and last name also?

If you are going to store the first and last name separately, then you need to read them in separately. If you are going to store them in the same string, then you MIGHT be able to read them in together, though it would probably be easier to read them in separately, combine them, and store them as a single thread. To sort you need to declare a number of arrays.

string lastName[20]; //all students last names
string firstName[20];//all students first names
int exam1[20];//all students scores for first exam
int exam2[20];//all students scores for second exam
...
int exam10[20];

Then read data from file into each of the arrays:

while stuff to read in
read in lastname;
read in firstName;
read in exam1;
.
.
.

then sort the lastName array, moving all data around at the same time in all the arrays to keep the data associated with the same name across arrays.

or

1)declare arrays as above;
2)declare a string to hold current name(s) and ints to hold current scores
3)read in a given students name(s) and scores.
4)find place in array where current student belongs, sorting by last name as insertion occurs
5)if necessary, make room for current student data by shifting current data with same or higher index than the one the current student will have one place to the right.
6)assign current students data into the array in the place desired.
7)use another int to keep track of how many students are present in the array at any given loop through the read/insertion
8)repeat until entire file read in

Then once sorting has been accomplished
1)output the name(s) in whatever format you want
2)calculate the average and grade (if not done already)
3)display each exam score, average, and letter grade as appropriate

Thank you, I will work this problem later at school!

Now, i have to leave!

i'll see how it goes, and if i'm able to do it! well i hope!

This article has been dead for over six months. Start a new discussion instead.