需要解决Makefile中的问题,以便在Storm数据程序中阅读

时间:2015-10-07 00:40:51

标签: c++ makefile

我必须创建一个程序来读取Storm.dat文件(包含海洋风暴并生成简要报告)。我已经制作了必要的文件,但是我遇到了Makefile的一些问题。

以下是我的代码:

storm.h

#ifndef STORMS_H
#define STORMS_H

class Storm
{
private:
    char where; // A, E, C
    char name[11]; // recall '\0'
    int seq; // sequence num 1...
    int year;
    int max_wind; // knots
    int min_press; // millibars or 10000 //
    char type; // H, S, D
public:
    Storm() ;// default constructor
    void print() const ;

    //5 accessors are code next..
    int get_seq() const;
    int get_year() const;
    int get_max_wind() const;
    int get_min_press() const;
    char get_type() const;

} ;

#endif

storm.cc

#include <iostream>
#include <iomanip> // re. setw, etc...
#include <cstring> // re. strcpy( dest, sorc ); etc... //
#include <cstdlib> // re. atoi

#include "storm.h"

using std::cout;
using std::endl;
using std::setw;
using std::left;
using std::right;

 const char* BASINS[] = { " ", "Atlantic", "Eastern Pacific", "Central Pacific" };

int i_basin( char c )
{
    if( c == 'A' ) return 1;
    if( c == 'E' ) return 2;
    if( c == 'C' ) return 3;
    return 0;
}

const char* TYPES[] = { " ", "Hurricane", "Storm", "Depression" };

int i_type( char c )
{
    if( c == 'H' ) return 1;
    if( c == 'S' ) return 2;
    if( c == 'D' ) return 3;
    return 0;
}

Storm::Storm() // default constructor
: where('N'), seq(0), year(0), max_wind(0), min_press(0), type('N')
{ strcpy( name, "None" ); }

void Storm::print() const
{   
    cout << left << setw(17) << BASINS[i_basin(where)]
         << setw(19) << TYPES[i_type(type)]
         << setw(11) << name
         << right << setw(2) << seq
         << '/' << year
         << setw(8) << max_wind;
    if( min_press )
        cout << setw(6) << min_press;
    cout << endl;
}

//5 accessors are coded here...
int Storm::get_seq() const { return seq; }
int Storm::get_year() const { return year; }
int Storm::get_max_wind() const { return max_wind; }
int Storm::get_min_press() const { return min_press; }
char Storm::get_type() const { return type; }

assign3_class_storm.cc

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

#include "storm.h"

using std::cout;
using std::endl;
using std::flush;
using std::cin;
using std::ios;

const char* HEADER =
    "Storm                               Name         Date     Wind  mbar\n"
    "--------------------------------------------------------------------\n";

const char* FNAME_BIN = "storm.dat";


typedef std::vector< Storm > Storms;

bool loadBinFile( const char* fname, Storms& vStorms ) ;
void showStorms( const Storms& vStorms );

template< typename T, typename Cmp >
void sel_sort( std::vector< T >& data, Cmp myCmp  );

// re. sort by increasing dates & seq...
int cmpByYear( const Storm& a, const Storm& b );
// re. sort by decreasing wind speed.
int cmpByWind( const Storm& a, const Storm& b );
// re. sort by increasing air pressure.
int cmpByPress( const Storm& a, const Storm& b );


int main() 
{
    Storms sList;
    if( loadBinFile( FNAME_BIN, sList ) )
    {
        cout << "Now showing sList loaded from file "
             << FNAME_BIN << endl;
        showStorms( sList );


        sel_sort( sList, cmpByYear);
        cout <<"\nSorted by dates ... \n";
        //showStorms( sList );

        sel_sort( sList, cmpByWind );
        cout <<"\nSorted by decreasing wind speed ... \n";
        //showStorms( sList );

        sel_sort( sList, cmpByPress );
        cout <<"\nSorted by increasing air pressure ... \n";
        //showStorms( sList );
    }


    cout << "Press 'Enter' to continue/exit ... " << flush;
    cin.get();

}

void showStorms( const Storms& vStorms )
{
    cout << "Total storms here is: " << vStorms.size() << endl;
    cout << HEADER;
    size_t i = 0;
    while(  i < vStorms.size()  )
    {
        vStorms[i].print();
        ++i;
        if( i % 20 == 0 )
        {
            cout << endl;

            cout << "Press 'Enter' to continue ... " << flush;
            cin.get();

            if( i != vStorms.size() )
                cout << HEADER;
        }
    }
}

bool loadBinFile( const char* fname, Storms& vStorms )
{
    fstream fs ;
    fs.open( fname, ios::in | ios::binary );
    if( fs )
    {
        Storm tmp;
        while( fs.read( (char*)&tmp, sizeof(Storm) ) )
            vStorms.push_back( tmp );
        fs.close();
        return true;
    }
    cout << "\nThere was a problem opening file "
              << fname << endl;
    return false;
}


template< typename T, typename Cmp >
void sel_sort( std::vector< T >& data, Cmp myCmp  )
{
    int len = data.size();
    int lenMinusOne = len-1;
    for( int j = 0; j <  lenMinusOne; ++ j )
    {
        int index_min = j;
        for( int i = j+1; i < len; ++ i )
            if(  myCmp(data[i], data[index_min] ) < 0 )
                index_min = i;
        // now swap ...
        T tmp = data[j];
        data[j] = data[index_min];
        data[index_min] = tmp;
    }
}


// re. sort by increasing dates & seq...
int cmpByYear( const Storm& a, const Storm& b )
{
    int cmp = a.get_year() - b.get_year();
    if( cmp == 0 )
        return a.get_seq() - b.get_seq();
    return cmp;
}

// re. sort by decreasing wind speed.
int cmpByWind( const Storm& a, const Storm& b )
{
    return b.get_max_wind() - a.get_max_wind();
}
// re. sort by increasing air pressure.
int cmpByPress( const Storm& a, const Storm& b )
{
    return a.get_min_press() - b.get_min_press();
}

如果有人能帮助我弄清楚我在创建Makefile时遇到的这些错误:

这是我的Makefile

output: assign3_class_storm.o storm.o
    g++ -o assign3_class_storm assign3_class_storm.o
    g++ -o storm storm.o

storm.o: storm.cc storm.h
    g++ -c storm.cc

assign3_class_storm.o: assign3_class_storm.cc storm.h
    g++ -c assign3_class_storm.cc

clean:
    -rm *.o assign3_class_storm storm

我得到的错误:

g++ -c assign3_class_storm.cc
g++ -c storm.cc
g++ -o assign3_class_storm assign3_class_storm.o
assign3_class_storm.o: In function `showStorms(std::vector<Storm, std::allocator<Storm> > const&)':
assign3_class_storm.cc:(.text+0x1a2): undefined reference to `Storm::print() const'
assign3_class_storm.o: In function `loadBinFile(char const*, std::vector<Storm, std::allocator<Storm> >&)':
assign3_class_storm.cc:(.text+0x2db): undefined reference to `Storm::Storm()'
assign3_class_storm.o: In function `cmpByYear(Storm const&, Storm const&)':
assign3_class_storm.cc:(.text+0x3d6): undefined reference to `Storm::get_year() const'
assign3_class_storm.cc:(.text+0x3e4): undefined reference to `Storm::get_year() const'
assign3_class_storm.cc:(.text+0x3fd): undefined reference to `Storm::get_seq() const'
assign3_class_storm.cc:(.text+0x40b): undefined reference to `Storm::get_seq() const'
assign3_class_storm.o: In function `cmpByWind(Storm const&, Storm const&)':
assign3_class_storm.cc:(.text+0x438): undefined reference to `Storm::get_max_wind() const'
assign3_class_storm.cc:(.text+0x446): undefined reference to `Storm::get_max_wind() const'
assign3_class_storm.o: In function `cmpByPress(Storm const&, Storm const&)':
assign3_class_storm.cc:(.text+0x46e): undefined reference to `Storm::get_min_press() const'
assign3_class_storm.cc:(.text+0x47c): undefined reference to `Storm::get_min_press() const'
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'output' failed
make: *** [output] Error 1

如果有人可以帮我解决这个问题,我真的很感激帮助。

由于

1 个答案:

答案 0 :(得分:0)

您的makefile设置为构建两个可执行文件stormassign3_class_storm。这毫无意义;您无法构建storm因为main()中没有storm.cc,并且您无法单独从assign3_class_storm构建assign3_class_storm.cc,因为它依赖于Storm的功能storm.cc类,在output: assign3_class_storm.o storm.o g++ -o storm assign3_class_storm.o storm.o 中定义。

首先让我们纠正这个核心问题:

storm: assign3_class_storm.o storm.o
    g++ -o storm assign3_class_storm.o storm.o

一旦完美运行(*),您可以通过将产品名称作为规则的名称来改进它(以便Make知道当文件已经存在并且是最新的时不需要执行规则):

storm: assign3_class_storm.o storm.o
    g++ -o $@ $^

一旦完美运行,您可以使用automatic variables

减少此规则的冗余
storm: assign3_class_storm.o storm.o
    @echo building $@...
    @g++ -o $@ $^

然后,如果你愿意,你可以使输出更简洁:

assign3_class_storm.cc

(*)您可能需要纠正#the sample N=dim(iris)[1] n=50 #sample size set.seed(123) si=iris[sample(N,n),c("Species","Sepal.Width")] #the "cumsum" lim=2.8 #for the conditional sum Sepal.Width=sapply(split(si,si$Species),function(x) sum(x$Sepal.Width >= lim)) sol=data.frame(Species=names(Sepal.Width),Sepal.Width) sol$ID=1:length(sol[,1]) sol # Species Sepal.Width ID # setosa setosa 18 1 # versicolor versicolor 8 2 # virginica virginica 14 3 中的一个小遗漏。