HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Utilizing std::map and std::array for displaying a modulus grid

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
stdmapgridutilizingarraydisplayingforandmodulus

Problem

I've written a modulus-type program (using std::vector). The user inputs a number, and the program displays a modulus grid pertaining to that number.

This is what it looks like (example program output with 12):

(0)  12 24  36  48  60  72  84  96  108  120
(1)  13  25  37  49  61  73  85  97  109  121
(2)  14  26  38  50  62  74  86  98  110  122
(3)  15  27  39  51  63  75  87  99  111  123
(4)  16  28  40  52  64  76  88  100  112  124
(5)  17  29  41  53  65  77  89  101  113  125
(6)  18  30  42  54  66  78  90  102  114  126
(7)  19  31  43  55  67  79  91  103  115  127
(8)  20  32  44  56  68  80  92  104  116  128
(9)  21  33  45  57  69  81  93  105  117  129
(10)  22  34  46  58  70  82  94  106  118  130
(11)  23  35  47  59  71  83  95  107  119  131
(12)  24  36  48  60  72  84  96  108  120  132


Now, I've decided to make it nicer by using std::map and std::array. I get the same output as before, but with the same alignment issues (fixing those could complicate my display function).

Is this an effective use of these containers (and am I using them correctly)? If not, what other containers could be used instead? I'm using std::array instead of std::vector here because I'm keeping the number of columns (array size) at 10.

#include 
#include 
#include 

const unsigned NUM_ARR_ELEMS = 10;

std::map> getModGrid(unsigned);
void displayModGrid(const std::map>&);

int main()
{
    std::map> modGrid;
    unsigned mod;

    std::cout  Mod: ";
    std::cin >> mod;

    std::cout > getModGrid(unsigned mod)
{
    std::map> modRow;
    std::array modValues;

    for (unsigned modIter = 0; modIter > &modGrid)
{
    for (auto rowIter = modGrid.cbegin(); rowIter != modGrid.cend(); ++rowIter)
    {
        std::cout first second.cbegin(); colIter != rowIter->second.cend(); ++colIter)
        {
            std::cout << *colIter << "  ";
        }

        std::cout << std::endl;
    }
}

Solution

-
main() can be defined lastly, so that the function prototypes can be removed. This will also allow NUM_ARR_ELEMS to be initialized within main(). The size of either the inner or outer structure can still be accessed via size().

-
For simple input like this, a command line argument is another option:

int main(int argc, char *argv[])
{
    unsigned int mod;

    // only argument being the file name
    if (argc < 2)
    {
        std::cin << mod;
    }
    // more than the file name, where only the second is used
    else
    {
        mod = std::atoi(argv[1]);
    }
}


Warning: std::atoi() returns an int, but mod is an unsigned int. As this is a mismatch (and should be reported by the compiler), something else should be changed. Either the return value of std::atoi() should be cast to an unsigned int, or mod should just be changed to an int (and adjusted elsewhere). The latter may be a better option here, and the extra unsigned bit really isn't important. Input validation (to avoid a negative value) can be done as well.

-
This type is quite long to copy in different places:

std::map>


so it can become a typedef:

typedef std::map> Grid;


-
Prefer "\n" over std::endl for just a newline. The latter also flushes the buffer.

Code Snippets

int main(int argc, char *argv[])
{
    unsigned int mod;

    // only argument being the file name
    if (argc < 2)
    {
        std::cin << mod;
    }
    // more than the file name, where only the second is used
    else
    {
        mod = std::atoi(argv[1]);
    }
}
std::map<unsigned, std::array<unsigned, NUM_ARR_ELEMS>>
typedef std::map<unsigned, std::array<unsigned, NUM_ARR_ELEMS>> Grid;

Context

StackExchange Code Review Q#26728, answer score: 2

Revisions (0)

No revisions yet.