How do I format the output of a row so that the columns are evenly centered?

In my java class, we wrote a card program where you select a "secret card" and at the end it tells you what your secret card is. I only have one problem and that is the formatting of the output. At the moment when it prints the first column, it is even the second and the third is not. My teacher told me to use spaces, but I tried that and didn't work. I know there is a way to format it, but I'm not sure. The result looks like this:

     Column 0           Column 1           Column 2
    ________________________________________________
     3 of Spades    3 of Diamonds  Ace of Diamonds
     9 of Diamonds    2 of Diamonds   10 of Diamonds
   Ace of Spades   10 of Hearts King of Clubs
     6 of Clubs    4 of SpadesQueen of Hearts
     5 of Diamonds    2 of Hearts    7 of Clubs
     2 of Spades Jack of Diamonds    3 of Hearts
     5 of Hearts    4 of Hearts    7 of Diamonds

      

My output code looks like this:

import java.util.Scanner;
import java.util.Random;

public class CardTrick {
  public static void main(String[] args) {

/* declare and initialize variables */
int column = 0, i = 0;
String name = " ";
String playAgain = " ";
String seeDeck = " ";

/* Declare a 52 element array of cards */
Card[] deck = new Card[52];

/* Declare a 7 by 3 array to receive the cards dealt to play the trick */
Card [][] play = new Card[7][3];

/* Declare a Scanner object for input */
Scanner input = new Scanner(System.in);

      

I can post all the code if you want, but I tried not to post much. I am very grateful for any help as I am new to Java.

+3


source to share


4 answers


I'm also going with a "format" suggestion, but mine is a little different.

In your program, you rely on your card toString

. So make it fixed-length formatted and then you can use them anywhere and they will take up the same space.

public String toString() {
    return String.format( "%5s of %-8s", rank, suit );
}

      



When you print this, you will have all your cards aligned to the "from" part, which I think is what you did in the first column of the output.

The "% 5s" part aligns the rank in a 5-character-wide field, and the "% -8s" part aligns the suit in an 8-character-wide field (which means there are extra spaces on the right if the suit is shorter than 8 characters).

+2


source


Please do some research before getting started with StackOverFlow with your question.

Have you ever heard of string formatting? You are using something similar to what you are probably using right now. It looks like you are typing with the System.out.print();

right? If so, you can use it System.out.printf();

together with %#

. Let me explain.

It looks like you want to print something similar to this.

Column 1     Column 2     Column 3
12           23           1234

      

Well, an easy way to solve it would be like this.

  int c1 = 12;
  int c2 = 23;
  int c3 = 1234;

  System.out.printf("%-22s%-22s%-22s\n","Column 1","Column 2","Column 3");
  System.out.printf("%-22d%-22d%-22d\n",c1,c2,c3);

      



Explain what is happening here, there is a lot going on there. Firstly, whenever you see a sign %

in System.out.printf()

, it means that a special (formatting in this case) action will be performed.

Now let's look at the parameters of the method. The method System.out.printf()

works by specifying the output format in the first parameter. Then the actual outputs are the following parameters. Do you see how it starts by specifying the format with "%-22s%-22s%-22s\n"

? Then it outputs them, separating them with commas? This is IMO the easiest way to format.

Finally, let me take another look at this thing that I mentioned earlier. Do you see the letters and numbers appearing -

after %

? All this also serves. - HERE is a good place to learn more, but I'll give you a basic rundown.

First, the negative sign indicates which side will get padding , padding is the space between the columns that makes them look pretty. Since it is negative, it will be on the right side (FYI, if there was no sign there, the padding will be on the left), so it will print your output, then add spaces to the right ... but how much space?

That's where this number comes in. 17 you can see how many spaces will be subtracted from the output length. In short, it will be simple and straightforward to make sure that every exit starts and ends at the same place. The only catch is to make sure the number 22 is greater than the maximum value of the String. I can see that the longest possible could be Queen of Diamonds

, so anything that should be greater than 19 I chose 22 because it looked better IMO.

What follows is a letter, this letter, as you can see, changes between the two conclusions. In this case, one says s, the other says d. An easy way to solve this, if your output is String, use s if it's and int (I don't think you need this, I just had to use my cuz my ints example), use d.

+5


source


Here's one way to do it.

Since you know that String

you will have the longest "Queen of Diamonds"

, you can base your split on your length. The way you do this, for each current line, add spaces to it until its length matches the length "Queen of Diamonds"

. Then you add any division you want, like a tab ( "\t"

).

Here's a sample program:

static String[] cards = { "3 of Spades", "3 of Diamonds", "Ace of Diamonds",
            "9 of Diamonds", "2 of Diamonds", "10 of Diamonds",
            "Ace of Spades", "10 of Hearts", "King of Clubs",
            "6 of Clubs", "4 of Spades", "Queen of Hearts",
            "5 of Diamonds", "2 of Hearts", "7 of Clubs",
            "2 of Spades", "Jack of Diamonds", "3 of Hearts",
            "5 of Hearts", "4 of Hearts", "7 of Diamonds" };

static String getSeparation(int len) {
     String longest = "Queen of Diamonds";
     StringBuilder sb = new StringBuilder();
     // add spaces to match the longest string
     for(int i = 0; i < longest.length() - len; i++) {
         sb.append(" ");
     }
     sb.append("\t"); // add separation tab
     return sb.toString();
 }

static void print() {
     for(int i = 0; i < cards.length; i += 3) {
         System.out.println(cards[i] + getSeparation(cards[i].length()) +
                            cards[i + 1] + getSeparation(cards[i + 1].length()) +
                            cards[i + 2] + getSeparation(cards[i + 2].length()));
     }
}

public static void main(String[] args) {
    print();
}

      

Output:

3 of Spades         3 of Diamonds       Ace of Diamonds     
9 of Diamonds       2 of Diamonds       10 of Diamonds      
Ace of Spades       10 of Hearts        King of Clubs       
6 of Clubs          4 of Spades         Queen of Hearts     
5 of Diamonds       2 of Hearts         7 of Clubs          
2 of Spades         Jack of Diamonds    3 of Hearts         
5 of Hearts         4 of Hearts         7 of Diamonds 

      

A shorter solution would be to use or format the output: String.format

System.out.printf

static String[] cards = { "3 of Spades", "3 of Diamonds",
        "Ace of Diamonds", "9 of Diamonds", "2 of Diamonds",
        "10 of Diamonds", "Ace of Spades", "10 of Hearts", "King of Clubs",
        "6 of Clubs", "4 of Spades", "Queen of Hearts", "5 of Diamonds",
        "2 of Hearts", "7 of Clubs", "2 of Spades", "Jack of Diamonds",
        "3 of Hearts", "5 of Hearts", "4 of Hearts", "7 of Diamonds" };

static void print() {
    int spacingSeparation = 3;                   // number of spaces between columns
    int longest = "Queen of Diamonds".length();  // length of the widest column
    int spacing = longest + spacingSeparation;   // total spacing
    for (int i = 0; i < cards.length; i += 3) {
        System.out.print(String.format(
                "%-" + spacing + "s%-" + spacing + "s%-" + spacing + "s\n",  // format
                cards[i], cards[i + 1], cards[i + 2]));                      // values
    }
}

public static void main(String[] args) {
    print();
}

      

Output:

3 of Spades         3 of Diamonds       Ace of Diamonds     
9 of Diamonds       2 of Diamonds       10 of Diamonds      
Ace of Spades       10 of Hearts        King of Clubs       
6 of Clubs          4 of Spades         Queen of Hearts     
5 of Diamonds       2 of Hearts         7 of Clubs          
2 of Spades         Jack of Diamonds    3 of Hearts         
5 of Hearts         4 of Hearts         7 of Diamonds  

      

+1


source


I would recommend placing tabs between columns. The only problem with using tabs is that the length of the lines can change, so the number of tabs used can change.

However, it's good that you know that the longest string is "Queen of Diamonds" and you can adjust it accordingly. My guess is two or three tab spaces will be enough, but you can play with it.

In other words, your code will look something like this:

// loop to deal card
for(row = 0; row <7; row++){
   for(col = 0; col < 3; col++){
    play[row][col] = deck[card];
    System.out.print(play[row][col].toString() + "\t\t\t"); // Change here.
    card++;
}

System.out.println();

      

-2


source







All Articles