1

After printing the deck to the screen, I want to save this 3D array into a text file. And ultimately be able to read this text file back into a deck of sorts. However, when I do all I get for a text file is "usdeck" represented in hex. I tried putting the below code but it doesnt work...help?

ofstream myfile;
myfile.open ("unshuffled deck.txt");
myfile << usdeck;
myfile.close;


// deck of cards
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
const char usdeck[4][13][14] = 
{
{"heart two", "heart three", "heart four",
"heart five", "heart six", "heart seven",
"heart eight","heart nine", "heart ten",
"heart jack","heart queen", "heart king",
"heart ace"},
{"diamond two", "diamond three", "diamond four",
"diamond five", "diamond six", "diamond seven",
"diamond eight", "diamond nine", "diamond ten",
"diamond jack", "diamond queen", "diamond king",
"diamond ace"},
{"club two", "club three", "club four", "club five",
"club six", "club seven", "club eight", "club nine",
"club ten", "club jack", "club queen", "club king",
"club ace"},
{"spade two", "spade three", "spade four",
"spade five", "spade six", "spade seven",
"spade eight", "spade nine", "spade ten",
"spade jack", "spade queen", "spade king",
"spade ace"}
};

for(int row=0;row<4; row++)
{
for(int column=0;column<13;column++)
    {
    for(int element=0;element<14;element++)
        {
    cout << usdeck[row][column][element] << " ";
        }
    cout <<endl;
}
}


return 0;

}
6
  • You do some work to output the text to 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 replace cout with myfile. Better still, write a function taking ostream& as a parameter and printing to that stream; then call it twice - once with cout and again with myfile. Commented Sep 3, 2014 at 23:26
  • i cant get the information to correctly write to a text file, it appears in chinese. i replaced cout with "myfile.txt" for example but when i open up the text file it is in chinese lettering? Commented Sep 3, 2014 at 23:28
  • I tried using ofstream myfile; myfile.open ("decktext.txt"); for(int row=0;row<4; row++) { for(int column=0;column<13;column++) { for(int element=0;element<14;element++) { myfile << usdeck[row][column][element] << " "; } myfile <<endl; } } myfile.close(); cout<< decktext.rdbuf(); Commented Sep 3, 2014 at 23:31
  • cout<< decktext.rdbuf(); This shouldn't compile. There is no variable named decktext declared in your program. Commented Sep 3, 2014 at 23:32
  • then how do i read from the text file i make back into the terminal Commented Sep 3, 2014 at 23:34

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.