tags:

views:

140

answers:

3

Hi all,

I was writing a sample example involving multiple files. The detailed code is as follows.

main.cpp

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include "grade.h"
#include "Student_Info.h"

using std::cin;
using std::cout;
using std::domain_error;
using std::endl;
using std::max;
using std::setprecision;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;

int main()
{
    vector<Student_Info> students;
    Student_Info record;
    string::size_type maxlen = 0;  //the length of the longest name

    //read and store all the student's data
    //Invariant: students contains all the student records read so far
    //maxlen contains the length of the longest name in students
    while(read(cin,record))
    {
     //find length of the longest name
     maxlen=max(maxlen,record.name.size());
     students.push_back(record);
    }

    //alphabetize the student records
    sort(students.begin(),students.end(),compare);

    //write the names and grades
    for(vector<Student_Info>::size_type i=0; i!=students.size();++i)
    {
     //write the name, padded to the right to maxlen + 1 characters
     cout << students[i].name << string(maxlen+1-students[i].name.size(),' ');

     //compute and write the grade
     try
     {
      double final_grade=grade(students[i]);
      streamsize prec = cout.precision();
      cout << setprecision(3) << final_grade << setprecision(prec);
     }
     catch(domain_error e)
     {
      cout << e.what();
     }

     cout << endl;
    }

    return 0;
}

Student_info.{h,cpp}

#ifndef GUARD_Student_Info
#define GUARD_Student_Info

#include <iostream>
#include <string>
#include <vector>

using std::iostream;
using std::string;
using std::vector;

struct Student_Info
{
    std::string name;
    double midterm,final;
    std::vector<double> homework;
};

bool compare(const Student_Info&, const Student_Info&);
std::istream& read(std::istream&, Student_Info&);
std::istream& read_hw(std::istream&, std::vector<double>&);

#endif
#include "Student_Info.h"

using std::istream;
using std::vector;

bool compare(const Student_Info& x, const Student_Info& y)
{
    return x.name < y.name;
}

istream& read(istream& is, Student_Info& s)
{
    is >> s.name >> s.midterm >> s.final;

    read_hw(is,s.homework); //read and store all the students' homework grades
    return is;
}

istream& read_hw(istream& in, vector<double>& hw)
{
    if(in)
    {
     //get rid of previous contents
     hw.clear();

     //read homework grades
     double x;
     while(in>>x)
      hw.push_back(x);

     //clear the stream so that the input would work for the next student
     in.clear();
    }

    return in;
}

grade.{h,cpp}

#ifndef GRADE_H
#define GRADE_H

//grade.h
#include <vector>
#include "Student_Info.h"

double grade(double,double,double);
double grade(double,double,const std::vector<double>&);
double grade(const Student_Info&);

#endif

#include <stdexcept>
#include <vector>

#include "median.h"
#include "grade.h"


double grade(const Student_Info& s)
{
    return grade(s.midterm,s.final,s.homework);
}

double grade(double midterm, double final, const vector<double>& hw)
{
    if(hw.size()==0)
     throw domain_error("student has done no homework");
    return grade(midterm, final, median(hw));
}

double grade(double midterm,double final,double homework)
{
    return 0.2*midterm + 0.4*final + 0.4*homework;
}

median.{h,cpp}

#ifndef MEDIAN_H
#define MEDIAN_H

#include <vector>         
#include <stdexcept>     //to get the declaration of domain_error
#include <algorithm>     //to get the declaration of sortt

using std::domain_error;
using std::sort;
using std::vector;

double median(std::vector<double>);

#endif
#include "median.h"

double median(vector<double> vec)
{
    typedef vector<double>::size_type vec_sz;

    vec_sz size=vec.size();
    if(size==0)
     throw domain_error("median of an empty vector");
    sort(vec.begin(),vec.end());

    vec_sz mid=size/2;

    return size%2==0 ? (vec[mid]+vec[mid-1])/2:vec[mid];
}

The problem is when I compile it using g++ on linux and run ./a.out nothing happens. This is strange. I have gone over the code but couldn't find anything untoward. Hopefully someone can find the glitch.

+4  A: 

Finding errors by visual inspection is often difficult - in our case, in particular because we still don't have the complete code (despite your posting of significant parts of it).

You should learn to use gdb, the GNU debugger. Compile your program with g++ -g, then run gdb a.out. Then, I recommend the following commands:

  • b main (sets a breakpoint on main)
  • r (starts the program, stops at main)
  • s (single-steps the program, so you can see why it is not doing anything)
Martin v. Löwis
The command `start` is equivalent to `b main` and `run`. It doesn't seem very well documented, but it's there.
greyfade
Interesting, thanks.
Martin v. Löwis
+5  A: 

By "nothing happens", do you mean that it's waiting for input and doesn't exit?

while(read(cin,record)) sure looks like that to me. Pass something via standard input.

hhaamu
+2  A: 

Are you providing input? This program is expecting to read a series of Student_Info records from standard input. If you have a file containing the student records you'll need to have a command line something like:

./a.out < student_records.txt
Charles E. Grant