-5

I would really like help with this program, as I can't figure out what to do. I've tried searching online for answers or something that would point me in the right direction, but this is sort of difficult for me since I'm just learning how to code. I would greatly appreciate it!

You are to write a program that will help Santa process the work done by his elves. You will be using a data file called elves.dat. There will be one line for each elf. That line will contain the name of the elf and the number of toys the elf made. You are to read from the file and place the values in parallel arrays. You do not know how many elves there are so you must read until the end of file and count. You will need a third parallel array of strings to record a rating for each elf. You should declare arrays with the capacity for 50 components.

The program should read into the arrays. It should look at the number of toys made by each elf and record a rating in a parallel array. The table below determines the ratings. The program should then print out the arrays side by side in neat, labeled columns. It should print out the total number of toys made by the elves, the number of elves who made more than 500 toys, the name of the elf who made the most toys, and the name of the elf who made the least toys. Each calculation should have a function of its own. NO output should be done in functions that do calculations. All output should be done in one output function. Remember to always pass the number of elements in the array with the array to functions.

Toys Made........Rating

500 or more: ***** 5 stars

between 300 and 499: *** 3 stars

between 200 and 299: * 1 star

under 200: - none

Here's the information in elves.dat: Smiley 662 Curley 88 Clementine 335 Jasper 105 Lucinda 775 Brunhilda 103 Florence 441 Oskar 820 Snowflake 990 Bernard 690 Punch 298 Chuckie 10 Frosty 102 Snowman 311 April 830 Merry 299 Sunshine 331 Buddy 1234 Carol 271 Misty 111 Harold 52 Henry 292 Twinkle 308 Starlight 703 Burr 112 Angelica 444 Bluenose 689 Harry 254 Twinkle 259 Stardust 121 Greensleeves 453 Noel 312 Happy 209 Yukon 534 Snowcap 190 Northpole 598

And here's my code, I feel like a have a very basic understanding, but I know I'm not even close! I would appreciate any help, I really need it.

#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

int main() {

  ifstream inFile;
  inFile.open("elves.dat");

  string elfName[50];
  int ToysMade[50];
  int count = 0;
  int i;
  //Read file until you've reached the end                                        
  while (!inFile.eof()){
    inFile >> elfName;
    inFile >> ToysMade;
    count++;}
    cout << "Elf: " << elfName <<endl;
    cout << "Toys made: " << ToysMade <<endl;

    inFile.close();
  return 0;
}
Yashas
  • 964
  • 1
  • 9
  • 29
  • 1
    Recommended read: [`while (!inFile.eof()){`](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – user0042 Dec 12 '17 at 03:35
  • 1
    How in Binky's name did putty get involved in this? If you are logging into a school server with putty to do work, consider instead downloading a C++ IDE an d doing the work locally. Odds are good that any IDE you select will have a built-in debugger that will make your software development experience orders of magnitude more fun. – user4581301 Dec 12 '17 at 03:40
  • 2
    Hello, and welcome to Stack Overflow! We are happy to help a programmer in a jam, but we won't do your homework for you. Instead of a general "What do I do" question with your homework pasted, how about you focus in on a specific part that you don't understand so that we know what you really need help with? Something like "How can I read in data from the file?" or "How do I call the function I want?". Break up the problem into manageable chunks, and attack them one at a time. That way, you aren't overcome by the massive amount of work to do with a general "I can't do it" attitude. – Davy M Dec 12 '17 at 03:41
  • It's like the old saying, how do you eat an enormous dinosaur? One bite at a time. (Well, I guess the newer phrase is "How do you eat an elephant," but it's the same point.) The more you simplify the problem into smaller "bites," the easier it becomes to manage. – Davy M Dec 12 '17 at 03:42
  • 1
    Note: You have been asked for three parallel arrays, but in the Real World (TM) you would use one array of a data structure. For example, `struct elfstats { string elfName; int ToysMade; string rating; };` and then `elfstats stats[50];` – user4581301 Dec 12 '17 at 03:43
  • 2
    Unrelated: An alternative to the dinosaur trick is to use a pair of binoculars. Turn the binoculars around and suddenly that huge dinosaur is small enough to eat with a knife and fork. – user4581301 Dec 12 '17 at 03:45
  • @user4581301 I think that goes around the purpose of the homework. – Yashas Dec 12 '17 at 05:05
  • 1
    @Yashas my friend, if I'm ever back in school and expected to eat a dinosaur as part of my homework, I'm switching majors. – user4581301 Dec 12 '17 at 05:10
  • I was referring to the idea of grouping the related data inside a struct. I believe this homework is to show the concept of parallel arrays. – Yashas Dec 12 '17 at 05:13
  • @DavyM thanks, you're right. Well I think that the main problem I am having right now is that I don't know how to retrieve the names and amount of toys made and then list them as output at the end. Also, we haven't learned about struct, so I don't think I should use it. – Chris Feld Dec 12 '17 at 05:23
  • http://idownvotedbecau.se/toomuchcode/ …and too much of the assignment. Please post only the code illustrating your problem, so your question and its answers can be useful for others in future. – Melebius Dec 12 '17 at 08:04
  • @Yashas you almost certainly believe correctly. I'm just trying to point out that what one does for class does not necessarily map well to practical programming. Apologies for not being clear. – user4581301 Dec 12 '17 at 18:40

1 Answers1

0

Based on what you stated: this is how I would design the program. I could have even made it simpler looking by using a struct or class, but I'm gathering you are not that far in your course of training. Even this might be a bit more advanced than what is being asked. You did mention parallel arrays. Instead of arrays I'm using std::vectors in place of it. You can easily swap out the vectors with regular arrays, however the functions for doing the calculations would change since I'm using library functions that work on containers. With raw arrays you would have to do a bunch of for & while loops and comparison checks while also doing bounds checks of those arrays. Your overall program would look similar to this.

#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <fstream>

// Typedefs
typedef std::vector<std::string> Strings;
typedef std::vector<unsigned> Values;

unsigned countToys( const Values& toys );
void determineRatings( const Values& toys, Values& ratings );
unsigned count5StarElves( const Values& toys );

std::string getBestElf( const Strings& elves, const Values& toys );
std::string getWorstElf( const Strings& elves, const Values& toys );

void displayStats( const unsigned numElves, const unsigned fiveStarElves,
                   const Strings& elves, const Values& toys, const Values& ratings,
                   const std::string& bestElf, const std::string& worstElf );

int main() {

    // Create Containers Giving 50 available spots.
    Strings elves;
    elves.resize( 50 );
    Values ratings;
    ratings.resize( 50 );
    Values toysMade;
    toysMade.resize( 50 );

    // Create, Open, Read From File & Close It
    unsigned numElves = 0;  
    std::ifstream file;
    file.open( "elves.dat" );
    while ( file >> elves[numElves] >> toysMade[numElves] ) {
        numElves++; // Need this to resize containers.
    }
    file.close();

    // Adjust containers to fit number of elves.
    const std::size_t newSize = numElves;
    elves.resize( newSize );
    ratings.resize( newSize );
    toysMade.resize( newSize );

    // Get The Stats -- Counting the total number of elves is called within the display function.
    determineRatings( toysMade, ratings );
    unsigned fiveStarElves = count5StarElves( ratings );
    std::string bestElf  = getBestElf( elves, toysMade );
    std::string worstElf = getWorstElf( elves, toysMade );

    // Display The Results
    displayStats( numElves, fiveStarElves, elves, toysMade, ratings, bestElf, worstElf );


    std::cout << "\nPress any key and enter to quit." << std::endl;
    char c;
    std::cin >> c;

    return 0;
}

unsigned countToys( const Values& toys ) {
    unsigned total = std::accumulate( toys.begin(), toys.end(), 0 );
    return total;
}

void determineRatings( const Values& toys, Values& ratings ) {
    for ( unsigned i = 0; i < toys.size(); i++ ) {
        if ( toys[i] >= 500 ) {
            ratings[i] = 5;
        }

        if ( toys[i] < 500 && toys[i] >= 300 ) {
            ratings[i] = 3;
        }

        if ( toys[i] < 300 && toys[i] >= 200 ) {
            ratings[i] = 1;
        }

        if ( toys[i] < 200 ) {
            ratings[i] = 0;
        }
    }
};

unsigned count5StarElves( const Values& ratings ) {
    unsigned fiveStartCount = 0;
    for ( auto val : ratings ) {
        if ( val == 5 ) {
            fiveStartCount++;
        }
    }

    return fiveStartCount;
}

std::string getBestElf( const Strings& elves, const Values& toys ) {
    auto it = std::max_element( toys.begin(), toys.end() );
    if ( it == toys.end() ) {
        return "";
    }

    // for random access containers with O(1) - constant
    return elves[it - toys.begin()];

    // If using non-random containers use the following with O(n) - linear
    // return std::distance(toys.begin(), it );
}

std::string getWorstElf( const Strings& elves, const Values& toys ) {
    auto it = std::min_element( toys.begin(), toys.end() );
    if ( it == toys.end() ) {
        return "";
    }

    // for random access containers with O(1) - constant
    return elves[it - toys.begin()];

    // If using non-random containers use the following with O(n) - linear
    // return std::distance(toys.begin(), it);
}

void displayStats( const unsigned numElves, const unsigned fiveStarElves, 
                   const Strings& elves, const Values& toys, const Values& ratings, 
                   const std::string& bestElf, const std::string& worstElf ) {

    std::cout << "***********************************************\n";
    std::cout << "* Welcome To Santa's Workshop:                *\n";
    std::cout << "* We have " << numElves << " working elves.                   *\n";
    std::cout << "* Our Elves made a total of " << countToys( toys ) << " toys today. *\n";
    std::cout << "***********************************************\n\n";
    std::cout << "Here are their stats:\n";
    std::cout << "===============================================\n";


    // Calculate the longest name for proper screen output formatting.
    std::size_t maxLength = 0;
    for ( const auto name : elves ) {
        if ( name.length() > maxLength ) {
            maxLength = name.length();
        }
    }

    std::cout << std::left << std::setw( maxLength + '\t' ) << "Elf Name:" << std::setfill( ' ' ) << "Toys Made:\t\tRating:\n" << std::endl;

    for ( unsigned i = 0; i < numElves; i++ ) {
        std::cout << std::left << std::setw( maxLength + '\t' ) << elves[i] << std::left << std::setfill( ' ' )
            << std::setw( 4 ) << std::left << toys[i] << std::left
            << "\t\t" << ratings[i] << " stars" << std::endl;
    }

    std::cout << "\n\n";

    // Additional Stats:
    std::cout << "There are " << fiveStarElves << " 5 Star Elves!\n";
    std::cout << "The Best Elf is: " << bestElf << std::endl;
    std::cout << "The Worst Elf is: " << worstElf << std::endl;
}

elves.dat

Smiley 662
Curley 88
Clementine 335
Jasper 105
Lucinda 775
Brunhilda 103
Florence 441
Oskar 820
Snowflake 990
Bernard 690
Punch 298
Chuckie 10
Frosty 102
Snowman 311
April 830
Merry 299
Sunshine 331
Buddy 1234
Carol 271
Misty 111
Harold 52
Henry 292
Twinkle 308
Starlight 703
Burr 112
Angelica 444
Bluenose 689
Harry 254
Twinkle 259
Stardust 121
Greensleeves 453
Noel 312
Happy 209
Yukon 534
Snowcap 190
Northpole 598

Edit - If you want to do something a little fancy in the display function. Change the displayStats() function to this:

void displayStats( const unsigned numElves, const unsigned fiveStarElves, 
                   const Strings& elves, const Values& toys, const Values& ratings, 
                   const std::string& bestElf, const std::string& worstElf ) {

    std::cout << "***********************************************\n";
    std::cout << "* Welcome To Santa's Workshop:                *\n";
    std::cout << "* We have " << numElves << " working elves.                   *\n";
    std::cout << "* Our Elves made a total of " << countToys( toys ) << " toys today. *\n";
    std::cout << "***********************************************\n\n";
    std::cout << "Here are their stats:\n";
    std::cout << "===============================================\n";


    // Calculate the longest name for proper screen output formatting.
    std::size_t maxLength = 0;
    for ( const auto name : elves ) {
        if ( name.length() > maxLength ) {
            maxLength = name.length();
        }
    }

    std::cout << std::left << std::setw( maxLength + '\t' ) << "Elf Name:" << std::setfill( ' ' ) << "Toys Made:\t\tRating:\n" << std::endl;

    // A little bit of magic: (not really) just pretty 
    Strings stars;
    std::string str;
    for each (auto star in ratings) {
        if ( star == 0 ) {
            str = std::string( "" );
        }

        if ( star == 1 ) {
            str = std::string( "*" );
        }

        if ( star == 3 ) {
            str = std::string( "***" );
        }

        if ( star == 5 ) {
            str = std::string( "*****" );
        }

        stars.push_back( str );
    }

    for ( unsigned i = 0; i < numElves; i++ ) {
        std::cout << std::left << std::setw( maxLength + '\t' ) << elves[i] << std::left << std::setfill( ' ' )
            << std::setw( 4 ) << std::left << toys[i] << std::left
            << "\t\t" << stars[i] /*ratings[i] << " stars"*/ << std::endl;
    }

    std::cout << "\n\n";

    // Additional Stats:
    std::cout << "There are " << fiveStarElves << " 5 Star Elves!\n";
    std::cout << "The Best Elf is: " << bestElf << std::endl;
    std::cout << "The Worst Elf is: " << worstElf << std::endl;
}
Sinister Beard
  • 3,615
  • 10
  • 53
  • 90
Francis Cugler
  • 7,462
  • 1
  • 24
  • 44