我必须创建一个程序来读取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
如果有人可以帮我解决这个问题,我真的很感激帮助。
由于
答案 0 :(得分:0)
您的makefile设置为构建两个可执行文件storm
和assign3_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
中的一个小遗漏。