I suggest you change your data structure. You are beginning to see the difficulties as you progress.
To write data to a file and read it back, you will need to structure the data for ease of reading. I recommend one entry per line. This will allow the use of the std::istream::getline function to read it back.
Pardon my style, but I like to place spaces between operators for readability. :-)
Output to file:
for (unsigned int r = 0; r < 4; ++r)
{
for (unsigned int c = 0; c < 13; ++c)
{
data_file << usdeck[r][c] << '\n';
}
}
Input from file:
for (unsigned int r = 0; r < 4; ++r)
{
unsigned int c = 0;
for (c = 0; c < 13; ++c)
{
// Read in the data and test for success.
if (!data_file.getline(&usdeck[r][c][0], '\n', 14))
{
break;
}
}
if (c < 13)
{
break;
}
}
A Better Data Structure
In my opinion, your data structure is difficult to use. Most computers were not designed to efficiently process text strings; they were designed to handle numbers more efficiently. So, let's use a data structure for numbers.
Since the quantities of cards in a suite is not negative and the number of suits in a deck is not negative, we'll use unsigned integers. This will allow the compiler to check our code for errors better.
Let's look at a deck. It is made up of 52 cards: 13 cards per suit and 4 suits. We could represent a card as some object that has a value and a suit:
enum Suit_Type {Heart, Diamond, Spade, Club};
struct Card
{
Suit_Type suit;
unsigned int value;
};
With this representation, every Card has a suit and a value.
So, a Deck must be a container of cards:
const unsigned int CARDS_PER_DECK = 52; // 13 cards per suit * 4 suits.
unsigned int Deck[CARDS_PER_DECK]; // A container of cards.
In most card games, card's don't stay in the deck, they move from deck to player. The array can be case that cards come in, but we need something more flexible. A data structure where we can remove cards from and the container will shrink to fit. Let's try std::vector:
std::vector<Card> deck1(CARDS_PER_DECK);
The std::vector can also be useful for each player:
std::vector<Card> player1;
std::vector<Card> player2;
Initialization of the deck is left as an exercise for the OP.
In most card games, cards travel from a central deck to a player:
player1.push_back(deck1.back());
deck.pop_back();
player2.push_back(deck1.back());
deck.pop_back();
Since this is C++, methods can be added to the Card structure for ordering, reading, and writing of Card instances.
Free standing functions can be created for analyzing a player's hand (which is a vector of cards).
Writing of a Card
A simple method for writing a card to an output stream:
struct Card
{
Suit_Type suit;
unsigned int value;
void write(std::ostream& out)
{
static const char value_name[] =
{
"zero", "Ace", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "jack", "queen", "king"
}
switch(suit)
{
case Heart: out << "heart "; break;
case Diamond: out << "diamond "; break;
case Spade: out << "spade "; break;
case Club: out << "club "; break;
}
out << value_name[value] << "\n"; // one card per line.
}
};
To output a card to the console:
Card c;
c.suite = Club;
c.value = 1;
c.write(cout);
To output a card to a file:
ofstream card_file("cards.txt");
c.write(card_file);
To output a player's hand:
std::vector<Card>::const_iterator iter;
for (iter = player1.begin();
iter != player1.end();
++iter)
{
iter->write(cout);
}
These are just a few of the benefits of changing your data structure.
cout- why do you believe that this work will just magically do itself when outputting to a stream backed by file, rather than console? You need to run the same loops, only replacecoutwithmyfile. Better still, write a function takingostream&as a parameter and printing to that stream; then call it twice - once withcoutand again withmyfile.cout<< decktext.rdbuf();This shouldn't compile. There is no variable nameddecktextdeclared in your program.