'C++ Arrays and writing of values

I'm trying to write a punnett square generator for a biology class, it's quite simple, but I can't figure out how to get the values to write to the other blocks. I can get the individual variables in, but I can't get the values to combine in the lower squares. Any help would be appreciated. Code is attached below.

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    char p_s[2][2] = {0};
    int i = 0;
    int j = 1;
    cout << "Input first parent's first gene.\n";
    cin >> p_s[i][j];
    j++;
    cout << "Input first parent's sencond gene.\n";
    cin >> p_s[i][j];
    system("Pause");
    cout << "First Gene: " << p_s[0][1] << endl << endl << "Second Gene: " << p_s[0][2];
    j = 0;
    i++;
    cout << endl << endl << "Input second parent's first gene: ";
    cin >> p_s[i][j];
    i++;
    cout << "Input second parent's second gene: ";
    cin >> p_s[i][j];
    cout << "First Gene: " << p_s[1][0] << endl << endl << "Second Gene: " << p_s[0][2];
    system("PAUSE");
    p_s[1][1] = p_s[0][1] p_s[1][0];
    cout << p_s[1][1];
    return 0;
}


Solution 1:[1]

First of all, I can see a problem with int j:

In line three you initialize it to one

int j = 1;

Three lines later you increment it up by one:

j++; // j is now equal to 2
//...
cin >> p_s[i][j]; // j is still equal to 2, which is outside of the array bounds!

This same thing happens in lines 10 and 18, where you attempt to access p_s[0][2], which is outside of the array's bounds.

Also, if you're looking to make a traditional punnett square, each square would require two char's worth of storage, which just isn't available with your current system (You'd need 8 char's, and p_s only has four).

However, if you were looking to revise your program, you could always try an object oriented approach, by splitting your punnett and parents into classes like this:

struct Parent
{
    std::string a;
    std::string b;

    Parent(std::string _a, std::string _b) : a(_a), b(_b) {}
}

And

struct Punnett
{
    std::vector<std::string> GeneCombos;

    Punnett (Parent one, Parent two) {
        GeneCombos.push_back(one.a + two.a);
        GeneCombos.push_back(one.a + two.b);
        GeneCombos.push_back(one.b + two.a);
        GeneCombos.push_back(one.b + two.b);
    }
}

This way you don't have to worry about the values of the Punnett square: They're created in the constructor.

If you wanted to go a step further, you could add to the constructors of both classes to make them assign their variables based on user input:

struct Parent
{
    std::string a;
    std::string b;

    Parent(std::string _a, std::string _b) : a(_a), b(_b) {}

    Parent() { //If no values are passed, it asks for them
        std::cout << "\nEnter Gene One: ";
        std::cin >> a;
        std::cout << "\nEnter Gene Two: ";
        std::cin >> b;
    }
};

And for the Punnett class:

class Punnett
{
    std::vector<std::string> GeneCombos;

public:
    void draw() {
        std::cout << "\nResulting Combinations:\n";
        for (unsigned int i = 0; i < 4; ++i)
            std::cout << GeneCombos[i] << '\n';
    }

    Punnett (Parent one, Parent two) {
        GeneCombos.push_back(one.a + two.a);
        GeneCombos.push_back(one.a + two.b);
        GeneCombos.push_back(one.b + two.a);
        GeneCombos.push_back(one.b + two.b);
    }
};

Using the modified classes, your main() would only be five lines long:

int main()
{
    Parent One;
    Parent Two;
    Punnett punnett(One, Two);
    punnett.draw();
    return 0;
}

Hoped this helped.

EDIT*: As Ben Voigt wisely pointed out, the Punnett::draw() function didn't belong in the constructor, and was moved to main().

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1