Thread: Help!!!!!!!!

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    23

    Unhappy Help!!!!!!!!

    My program compiles perfectly, but I can't get it to work. I'm kind of new at C++ so it's very possible that I'm overlooking something.
    Here's my program and a segment from the input file is after the program:
    // necessary library header files:
    #include<iostream.h>
    #include<fstream.h>
    #include<iomanip.h>
    #include<string.h>

    // global user-defined types:
    struct Storm {
    int beginDate;
    int duration;
    char name[15];
    int category;
    int wind;
    int pressure;
    };

    // function prototypes:
    int GetRecord( ifstream &input, int &y,int &m, int &d, int &h,
    int &s, char name[], int &wind, int &pres);
    Storm* GetStorm( ifstream& input );
    int SaffirSimpson( int w );
    void Sort( Storm* List[], int NStorms );
    void DisplayStorms( const char* title, Storm* List[], int NStorms );
    void PrintStorm( Storm* StormPointer );

    // Constants
    const int MAX_STORMS = 200;
    const float KnotsToMPH = 1.15;

    int main( void ) {
    Storm* List[MAX_STORMS];
    Storm* CurrentStorm; // storm returned by GetStorm
    int NStorms = 0; // number in aray List
    int Total = 0; // total number of storms in the input file

    // replace with interactive version
    ifstream input("HurricaneTestFile.Data");

    // while we have storms to process
    while( (CurrentStorm = GetStorm( input ) ) != NULL ) {
    ++Total;
    if( CurrentStorm->category < 3 )
    delete CurrentStorm;
    else
    List[NStorms++] = CurrentStorm;
    }

    input.close();

    cout << "Number of storms: " << Total << endl;
    cout << "Hurricanes with category 3 and above: " << NStorms << endl;
    DisplayStorms("First Ten Storms", List, 10 );

    Sort( List, NStorms);
    DisplayStorms("Top Ten Storms", List, 10 );

    }

    int GetRecord( ifstream &in, int &year, int &month, int &day, int &hour,
    int &seq, char name[], int &wind, int &pres ) {
    // reads one "record" from the input, and stores in reference arguments
    // returns 0 if end-of-file, 1 if record read

    float junk;

    if (!(in.eof())) {
    in >> year >> month >> day >> hour >> seq >> name
    >> junk >> junk >> wind >> pres;
    return 1;
    }

    return 0;
    }

    Storm* GetStorm( ifstream& in ) {
    // Build a Storm structure, and return the poointer
    // static is necesary to save the last record read for
    // the next storm.

    static int year = 0, month, day, hour, seq, wind, pressure;
    static char name[15];
    static status = 1;
    int current, cat;
    Storm* NewStorm; // we'll return this pointer to the new storm object
    double mph;
    // If the last storm caused end-of-file, we're done.(return NULL)
    if( status == 0 )
    return NULL;

    // If this is the first time this function is called,
    // then read first record.
    if( year == 0 )
    GetRecord(in, year, month, day, hour, seq, name, wind, pressure);

    // Make a storm object and initialize it with info from the current record
    NewStorm = new Storm;
    NewStorm->beginDate = (year * 1000) + (month * 100) + day;
    NewStorm->duration = hour;
    strcpy(NewStorm->name, name);
    NewStorm->wind = wind;
    NewStorm->pressure = pressure;

    current = seq;

    // Now, keep reading records as long as they go with this storm.
    // Watch out for end-of-file!
    status = GetRecord(in, year, month, day, hour, seq, name, wind, pressure);
    while((strcmp(NewStorm->name, name) == 0) && (status == 1)) {
    //update storm info:
    NewStorm->duration += 6;
    if(NewStorm->wind < wind)
    NewStorm->wind = wind;
    if(((pressure < NewStorm->pressure) && pressure != 0) || NewStorm->pressure == 0 )
    NewStorm->pressure = pressure;
    cat = SaffirSimpson(NewStorm->wind);
    if(cat > NewStorm->category)
    NewStorm->category = cat;
    //get next record
    GetRecord(in, year, month, day, hour, seq, name, wind, pressure);
    }

    // convert from knots to mph
    NewStorm->wind *= KnotsToMPH;

    // and return the pointer to the new storm object:
    return NewStorm;
    }

    void PrintStorm( Storm* ptr ) {
    // display one storm
    cout << ptr->beginDate << ptr->duration << ptr->name << ptr->category
    << ptr->wind << ptr->pressure << endl;

    return;
    }

    void DisplayStorms( const char* title, Storm* List[], int NStorms ) {
    // display NStorms storms
    // print some title and column headings; make a loop
    // and invoke function "PrintStorm" for each storm.

    cout << "Begin Date" << setw(10) << "Duration (hours)" << "Name" << setw(10)
    << "Category" << "Maximum Winds (mph)"
    << "Minimum Pressure (mb)" << endl;
    cout << "----------------------------------------------------------------" << endl;
    for(int i = 0; i < NStorms; i++)
    PrintStorm(*List);
    return;
    }

    int SaffirSimpson( int wind ) {
    // Compute storm category, using the Saffir-Simpson scale

    int category;

    if(wind > 134)
    category = 5;
    else if ((wind < 134) && (wind > 113))
    category = 4;
    else if ((wind < 113) && (wind > 96))
    category = 3;
    else if ((wind < 96) && (wind > 83))
    category = 2;
    else if ((wind < 83) && (wind > 64))
    category = 1;
    else if ((wind < 64) && (wind > 34))
    category = 'TS';
    else
    category = 'TD';

    return category;
    }

    void Sort( Storm* x[], int N ) {
    // bubble sort the list of Storm pointers
    int pass = 0, k, switches;
    Storm* temp;

    switches = 1;

    while( switches ) {
    switches = 0;
    pass++;
    for( k = 0; k < N - pass; k++ ) {
    if(x[k]->category < x[k + 1]->category) {
    temp = x[k];
    x[k] = x[k + 1];
    x[k + 1] = temp;
    switches = 1;
    }
    }
    }

    return;
    }


    A segment of the input file:
    1964 9 20 18 9 GLADYS 29.4 69.7 90 964
    1964 9 21 0 9 GLADYS 29.8 69.6 90 964
    1964 9 21 6 9 GLADYS 30.4 69.6 85 0
    1964 9 21 12 9 GLADYS 31.1 69.8 85 980
    1964 9 21 18 9 GLADYS 32.2 70.4 80 977
    1964 9 22 0 9 GLADYS 33.1 71.0 80 984

  2. #2
    Unleashed
    Join Date
    Sep 2001
    Posts
    1,765

    hmmmmm

    Code:
    My program compiles perfectly, but I can't get it to work. I'm kind of new at C++ so it's very possible that I'm overlooking something. 
    Here's my program and a segment from the input file is after the program: 
    // necessary library header files: 
    #include<iostream.h> 
    #include<fstream.h> 
    #include<iomanip.h> 
    #include<string.h> 
    
    // global user-defined types: 
    struct Storm { 
    int beginDate; 
    int duration; 
    char name[15]; 
    int category; 
    int wind; 
    int pressure; 
    }; 
    
    // function prototypes: 
    int GetRecord( ifstream &input, int &y,int &m, int &d, int &h, 
    int &s, char name[], int &wind, int &pres); 
    Storm* GetStorm( ifstream& input ); 
    int SaffirSimpson( int w ); 
    void Sort( Storm* List[], int NStorms ); 
    void DisplayStorms( const char* title, Storm* List[], int NStorms ); 
    void PrintStorm( Storm* StormPointer ); 
    
    // Constants 
    const int MAX_STORMS = 200; 
    const float KnotsToMPH = 1.15; 
    
    int main( void ) { 
    Storm* List[MAX_STORMS]; 
    Storm* CurrentStorm; // storm returned by GetStorm 
    int NStorms = 0; // number in aray List 
    int Total = 0; // total number of storms in the input file 
    
    // replace with interactive version 
    ifstream input("HurricaneTestFile.Data"); 
    
    // while we have storms to process 
    while( (CurrentStorm = GetStorm( input ) ) != NULL ) { 
    ++Total; 
    if( CurrentStorm->category < 3 ) 
    delete CurrentStorm; 
    else 
    List[NStorms++] = CurrentStorm; 
    } 
    
    input.close(); 
    
    cout << "Number of storms: " << Total << endl; 
    cout << "Hurricanes with category 3 and above: " << NStorms << endl; 
    DisplayStorms("First Ten Storms", List, 10 ); 
    
    Sort( List, NStorms); 
    DisplayStorms("Top Ten Storms", List, 10 ); 
    
    } 
    
    int GetRecord( ifstream &in, int &year, int &month, int &day, int &hour, 
    int &seq, char name[], int &wind, int &pres ) { 
    // reads one "record" from the input, and stores in reference arguments 
    // returns 0 if end-of-file, 1 if record read 
    
    float junk; 
    
    if (!(in.eof())) { 
    in >> year >> month >> day >> hour >> seq >> name 
    >> junk >> junk >> wind >> pres; 
    return 1; 
    } 
    
    return 0; 
    } 
    
    Storm* GetStorm( ifstream& in ) { 
    // Build a Storm structure, and return the poointer 
    // static is necesary to save the last record read for 
    // the next storm. 
    
    static int year = 0, month, day, hour, seq, wind, pressure; 
    static char name[15]; 
    static status = 1; 
    int current, cat; 
    Storm* NewStorm; // we'll return this pointer to the new storm object 
    double mph; 
    // If the last storm caused end-of-file, we're done.(return NULL) 
    if( status == 0 ) 
    return NULL; 
    
    // If this is the first time this function is called, 
    // then read first record. 
    if( year == 0 ) 
    GetRecord(in, year, month, day, hour, seq, name, wind, pressure); 
    
    // Make a storm object and initialize it with info from the current record 
    NewStorm = new Storm; 
    NewStorm->beginDate = (year * 1000) + (month * 100) + day; 
    NewStorm->duration = hour; 
    strcpy(NewStorm->name, name); 
    NewStorm->wind = wind; 
    NewStorm->pressure = pressure; 
    
    current = seq; 
    
    // Now, keep reading records as long as they go with this storm. 
    // Watch out for end-of-file! 
    status = GetRecord(in, year, month, day, hour, seq, name, wind, pressure); 
    while((strcmp(NewStorm->name, name) == 0) && (status == 1)) { 
    //update storm info: 
    NewStorm->duration += 6; 
    if(NewStorm->wind < wind) 
    NewStorm->wind = wind; 
    if(((pressure < NewStorm->pressure) && pressure != 0) || NewStorm->pressure == 0 ) 
    NewStorm->pressure = pressure; 
    cat = SaffirSimpson(NewStorm->wind); 
    if(cat > NewStorm->category) 
    NewStorm->category = cat; 
    //get next record 
    GetRecord(in, year, month, day, hour, seq, name, wind, pressure); 
    } 
    
    // convert from knots to mph 
    NewStorm->wind *= KnotsToMPH; 
    
    // and return the pointer to the new storm object: 
    return NewStorm; 
    } 
    
    void PrintStorm( Storm* ptr ) { 
    // display one storm 
    cout << ptr->beginDate << ptr->duration << ptr->name << ptr->category 
    << ptr->wind << ptr->pressure << endl; 
    
    return; 
    } 
    
    void DisplayStorms( const char* title, Storm* List[], int NStorms ) { 
    // display NStorms storms 
    // print some title and column headings; make a loop 
    // and invoke function "PrintStorm" for each storm. 
    
    cout << "Begin Date" << setw(10) << "Duration (hours)" << "Name" << setw(10) 
    << "Category" << "Maximum Winds (mph)" 
    << "Minimum Pressure (mb)" << endl; 
    cout << "----------------------------------------------------------------" << endl; 
    for(int i = 0; i < NStorms; i++) 
    PrintStorm(*List); 
    return; 
    } 
    
    int SaffirSimpson( int wind ) { 
    // Compute storm category, using the Saffir-Simpson scale 
    
    int category; 
    
    if(wind > 134) 
    category = 5; 
    else if ((wind < 134) && (wind > 113)) 
    category = 4; 
    else if ((wind < 113) && (wind > 96)) 
    category = 3; 
    else if ((wind < 96) && (wind > 83)) 
    category = 2; 
    else if ((wind < 83) && (wind > 64)) 
    category = 1; 
    else if ((wind < 64) && (wind > 34)) 
    category = 'TS'; 
    else 
    category = 'TD'; 
    
    return category; 
    } 
    
    void Sort( Storm* x[], int N ) { 
    // bubble sort the list of Storm pointers 
    int pass = 0, k, switches; 
    Storm* temp; 
    
    switches = 1; 
    
    while( switches ) { 
    switches = 0; 
    pass++; 
    for( k = 0; k < N - pass; k++ ) { 
    if(x[k]->category < x[k + 1]->category) { 
    temp = x[k]; 
    x[k] = x[k + 1]; 
    x[k + 1] = temp; 
    switches = 1; 
    } 
    } 
    } 
    
    return; 
    } 
    
    
    A segment of the input file: 
    1964 9 20 18 9 GLADYS 29.4 69.7 90 964 
    1964 9 21 0 9 GLADYS 29.8 69.6 90 964 
    1964 9 21 6 9 GLADYS 30.4 69.6 85 0 
    1964 9 21 12 9 GLADYS 31.1 69.8 85 980 
    1964 9 21 18 9 GLADYS 32.2 70.4 80 977 
    1964 9 22 0 9 GLADYS 33.1 71.0 80 984
    Beginner hu? Not really. If you are, your definately catching on fast. That is FAR from doing math, or Hello World. If no one answers such a long question, try CodeGuru.com, they'll help you out.
    The world is waiting. I must leave you now.

  3. #3
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    I took look at your code, you need to do better error checking. When opening
    files you should check they are opened properly.

    [code[
    while( (CurrentStorm = GetStorm( input ) ) != NULL
    [/code]
    You keep looping with out checking if NStorms is over MAX_STORMS

    your *current* bug is due to this line

    Code:
    DisplayStorms("First Ten Storms", List, 10 );
    NStorms is 0 but your passing 10 in. This causes a segfault.
    and there's a second one following that one.

    Sorry but it's hard to tell what the program is supposed to do so I can't help you
    too much. Try to avoid the static variables in GetStorm. If you are using static
    variables I think it will be more clear if you keep a static counter such as
    num_calls, instead of using year for two different purposes.

  4. #4
    Registered User
    Join Date
    Aug 2001
    Posts
    155
    Having code that compiles but doesn't run or produces unexpected results is par for the course in learning how to write programs. The resultant debugging process is a good learning experience. A common saying is that writing the code is 10% of the work but debugging is 90% of the code. You can minimize the chances of having unrunnable code by trying to break down you code into smaller fragments and make sure each additional fragment does what you think before moving on. If you are not familiar with the debugger that (probably) came with your compiler I recommend you learn how to use it, too.

    Overwriting arrays or initiating an endless loop is a common cause for code that compiles but doesn't "run". If there is no obvious evidence for that, then there is nothing like taking it line by line to work out the quirks.

    OFten I find that restating the goal of the project is important to understand where things went wrong. Looking at your code it appears that you want to create a summary of data contained in a file. The file data contains all the baseline information, some of which is used straight up, some of which needs to be manipulated, and some of which needs to be ignored. The information is about storms. The information is stored as a given assessment of a given storm all on one line, which you call a record. There may be more than one record per storm, in which case it is a follow up evaluation 6 hours after the previous evaluation. The data fields in the file are not of fixed length, but are in fixed order and a space delimited.

    The summary is to contain information about how many unique storms are evaluated in the file. You will store only those storms whose severity is greater than 2 (category 3 or above) in a array of up to 200 storms which will then serve as a source for printout of the most severe storms (up to the top ten) and (up to) the first 10 severe storms found in the file in sequence of being found. The summary will indicate how many of the storms found are saved in the array. The array will actually be an array of pointers to the storms, and the storms will be stored on the free store using the new operator.

    You intend to use streams to handle the file and the >> to extract the data and place it (eventually) into appropriate data members of a struct called Storm. The names of the storms in the file will be unique. You intend to pull the data for a given record out of the file, and compare the name of the record to the name of a unique storm. If they are the same, update data in the unique form such that after all data for a given storm is reviewed the maximum category, maximum wind, minimal pressure values, and totla duration will be saved for the summary. If the names are different, then assume all data regarding the unique storm have been reviewed and pass it on for further processing. passing the current record into the uniques storm location. If there is no unique storm available it is because there are no records in the file or this is the first record read in. If there is not further record in the file then the unique storm remaining in the data gathering module should be forwarded for further processing.

    Processing done outside the primary data gathering module includes evaluating the maximal category for each unique storm to decide whether to save it or not.

    Once all unique storms have be reviewed and saved or discarded, the first ten (or fewer if such is the case) will be printed out in sequence. Then the array will be sorted based on severity category, and printed out in sequence of worst severity to least severe with 10 maximal, fewer if appropriate, storms being printed out. The print outs will include date of onset, duration, name, category, wind, and pressure in that order.

    It looks like you try to change the file data regarding date into a single variable called beginDate of type int. If you try to use year *10000 + month * 100 + day so you get something like this: 19640551 it is difficult to read, and will be way out of bounds for a routine int (which is actually type short), although it should be ok as type long. A alternate way to handle dates is to use a struct to hold the information regarding year, month, date, and then manipulate the entire struct or one of the data member(s) of the struct as needed if you want/need, for example, to sort by date or whatever.

    For functions with return type void do not use a return; statement. Leave return out of it completely.

    Try to keep your conditionals as straightforward as possible:

    while( (CurrentStorm = GetStorm( input ) ) != NULL )

    is not in that category.

    In your print fucntion remember to put appropriate spacing to match your column title spacing.

    If you rearrange the flow of your program you can get by without use of static variables. Try declaring two variables of type Storm to hold data as it is read in. One could be currentStorm which holds the data as it is read out. The other could be uniqueStorm, which is assigned values only when a new storm name is encountered. Loop through the file comparing currentStorm to uniqueStorm, updating maneuvering etc. Only if values in uiniqueStorm are going to be stored in the array do you need to put values in a variable of type Storm declared on the free store.

    It's probably a typo, but the fucntion definition for GetRecord() is located in main(), which is a no-no.

    struct Date
    {
    int year;
    int month;
    int day;
    };

    struct Storm
    {
    Date beginDate;
    //etc;
    };

    void AnalyzeStorm(Storm, Storm *[], int &);
    //other functions to manipulate data read in

    intmain()
    {
    int numberOfRecords = 0;
    int numberOfUniqueStorms = 0;
    int NStorms = 0;

    float junk;

    char blank[] = " ";

    Storm currentStorm;
    Storm uniqueStorm;
    Storm * savedStorm[200];

    uniqueStorm.duration = 0;
    strcpy(uniqueStorm.name, blank);
    uniqueStorm.wind = 0;
    uniqueStorm.pressure = 30000;

    ifstream input(//whatever);

    input >> currentStorm.beginDate.year;
    while(!fin.eof())
    {
    input >> currentStorm.beginDate.month;
    //etc. to read in other data
    input >> currentStorm.pressure;
    numberOfRecords++;
    if uniqueStorm.name is blank
    then store values of currentStorm in uniqueStorm
    else if uniqueStorm.name is not blank
    if uniqueStorm.name is same as currentStorm.name
    then update uniqueStorm data as appropriate.
    else if uniqueStorm.name not same as currentStorm.name
    uniqueStorm++ and
    AnalyzeStorm(uniqueStorm, savedStorms, NStorms) and
    assign values of currentStorm to uniqueStorm
    input >> currentStorm.beginDate.year;
    }

    //Now run reports
    cout << numberOfRecords << ' ' << numberOfUniqueStorms << ' ' << NStorms << endl;

    if NStorms < 10
    then display NStorms number of storms in savedStorms using loop
    else display just first 10 storms.

    Sort Storms based on appropriate criteria
    Repeat display process.

    use loop to delete NStorm number of pointers in savedStorms;

    return 0;
    }
    //////////////////////////////////////////////////////////////
    void AnalyzeStorms(Storm UniqueStorm, Storm * savedStorms[], int & NStorms)
    {
    if UniqueStorm.category > 2
    then declare a Storm pointer, newStorm, on free store with new operator and
    transfer data from uniqueStorm to the Storm pointed to by
    newStorm and
    store newStorm at savedStorms[NStorms++]
    }
    /////////////////////////////////////////////////
    //function definitions for funcitons to manipulate data

    int SaffirSimpson( int wind ) {
    // Compute storm category, using the Saffir-Simpson scale

    int category;

    if(wind > 134)
    category = 5;
    else if ((wind < 134) && (wind > 113))
    category = 4;
    else if ((wind < 113) && (wind > 96))
    category = 3;

    /*
    //the rest of this isn't necessary. anything less than category 3
    //will not be saved for display or further use anyway so just
    //return a category 2 and don't worry about how to return a
    //category 4 (which is an int) vs a category 'TS' (whcih is a string,
    //and not ever a char as typed

    else if ((wind < 96) && (wind > 83))
    category = 2;
    else if ((wind < 83) && (wind > 64))
    category = 1;
    else if ((wind < 64) && (wind > 34))
    category = 'TS';
    else
    category = 'TD';
    */
    else category = 2;
    return category;
    }

    Enough rambling for now.
    Hi oh Silver! Away!

Popular pages Recent additions subscribe to a feed