Java 如何格式化字符串输出,使列均匀居中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26576909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:51:25  来源:igfitidea点击:

How to format string output, so that columns are evenly centered?

java

提问by guinea2

In my java class we wrote a card program in which you choose a "secret card", and at the end it tells you what your secret card was. I am only having one issue, and that is formatting the output. As of right now, when it prints the fist column is even but the 2nd and 3rd are not. My teacher said to use spaces, but I have tried this and does not work. I know there is a way to format it but am unsure. The output looks like this:

在我的 java 课中,我们编写了一个卡片程序,您可以在其中选择一张“秘密卡片”,最后它会告诉您您的秘密卡片是什么。我只有一个问题,那就是格式化输出。截至目前,当它打印第一列是偶数但第二和第三不是。我的老师说要使用空格,但我试过了,但不起作用。我知道有一种方法可以格式化它,但我不确定。输出如下所示:

     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 Hyman of Diamonds    3 of Hearts
     5 of Hearts    4 of Hearts    7 of Diamonds

My output code is as follows:

我的输出代码如下:

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);

If you want I can post the entire code, but I was trying not to post a lot. I greatly appreciate any help, being I am new to Java.

如果你愿意,我可以发布整个代码,但我尽量不发布很多。我非常感谢任何帮助,因为我是 Java 新手。

采纳答案by RealSkeptic

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

我也同意“格式”建议,但我的有点不同。

In your program, you're relying on your card's toString. So make that formatted in a fixed length, and then you can use them anywhere and they will take up the same space.

在您的程序中,您依赖于您的卡的toString. 因此,将其格式化为固定长度,然后您可以在任何地方使用它们,它们将占用相同的空间。

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

When you print this out, you'll have all your cards aligned on the "of" part, which I think is what you were going for in your first output column.

当您打印出来时,您会将所有卡片对齐在“of”部分,我认为这就是您在第一个输出列中想要的。

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

"%5s" 部分在 5 个字符宽的字段中右对齐排名,而 "%-8s" 部分在 8 个字符宽的字段中左对齐西装(这意味着如果西装在右边有额外的空格少于 8 个字符)。

回答by AdamMc331

I would recommend putting tabs in between the columns. The only problem with using tabs would be that the lengths of the strings can vary, so the number of tabs you use might change.

我建议在列之间放置标签。使用制表符的唯一问题是字符串的长度可能会有所不同,因此您使用的制表符数量可能会发生变化。

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

然而,好消息是您知道最长的字符串是“钻石皇后”,您可以相应地进行调整。我的猜测是两三个制表符空间就足够了,但您可以使用它。

In other words, your code would 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();

回答by nem035

Here is one way of doing it.

这是一种方法。

Since you know the longest Stringyou will have is "Queen of Diamonds", you can base your separation on its length. The way you would do this is, for each current string, add spaces to it until its length matches the length of "Queen of Diamonds". Then you add whatever separation you want, for example a tab ("\t").

由于您知道最长的String"Queen of Diamonds",因此您可以根据其长度进行分隔。执行此操作的方法是,对于每个当前字符串,为其添加空格,直到其长度与"Queen of Diamonds". 然后添加任何您想要的分隔符,例如制表符 ( "\t")。

Here is 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", "Hyman 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         Hyman of Diamonds    3 of Hearts         
5 of Hearts         4 of Hearts         7 of Diamonds 

A shorter solution would be to use String.formator System.out.printfto format the output:

更短的解决方案是使用String.formatSystem.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", "Hyman 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         Hyman of Diamonds    3 of Hearts         
5 of Hearts         4 of Hearts         7 of Diamonds  

回答by DreadHeadedDeveloper

You use something similar to what you are probably using right now. It looks like you are printing out using System.out.print();right? If so, you can use System.out.printf();along with %#. Let me explain.

您使用的东西与您现在可能正在使用的东西相似。看起来您正在使用System.out.print();正确的方式打印出来?如果是这样,您可以System.out.printf();%#. 让我解释。

It looks like you want to print out something that looks like this.

看起来你想打印出看起来像这样的东西。

Column 1     Column 2     Column 3
12           23           1234

Well, the easy way to solve for that 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);

Let's explain what is going on here, there's a lot of stuff happening. First, whenever you see a %sign in System.out.printf(), it means a special (formatting in this case) action is about to follow.

让我们解释一下这里发生了什么,发生了很多事情。首先,每当您看到%登录时System.out.printf(),就意味着即将进行特殊(在本例中为格式化)操作。

Now, let's look at the parameters of the method. The way System.out.printf()works is by specifying the format of the output 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 actually outputs them, separated by commas? That's IMO the easiest way to format.

现在,让我们看看该方法的参数。System.out.printf()工作方式是在第一个参数中指定输出的格式。然后,实际输出是以下参数。你看到它是如何通过指定格式开始的"%-22s%-22s%-22s\n"吗?然后,它实际上输出它们,用逗号分隔?这是 IMO 最简单的格式化方法。

Lastly, let's look some more at that special action thing I mentioned earlier. You see how there are letters and numbers and -after the %? Those all serve purposes too. --HERE--is a good place to learn more but I'll give you the basic rundown.

最后,让我们再看看我之前提到的那个特殊动作。你看怎么有字母和数字以及-后面的%?这些也都是有目的的。--HERE--是了解更多信息的好地方,但我会给你一个基本的概要。

First, the negative sign specifies which side will receive 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, padding would be on the left) so it will print out your output, then add spaces to the right... but how many spaces?

首先,负号指定哪一侧将接收padding, padding 是列之间的空间,使它们看起来很漂亮。由于它是负数,它将在右侧,(仅供参考,如果那里没有符号,则填充将在左侧)所以它会打印出您的输出,然后在右侧添加空格......但是有多少空间?

That's where that number comes in. The 17's you see are how many spaces there will be subtracted from the length of the output. Long story short, it will plainly and simply make sure each output starts and ends at the same place. The only catch is, make sure that the number, 22, is longer than the maximum possible String. I see the longest one possible would be Queen of Diamondsso anything bigger than 19 should do it, I chose 22 cuz it looked better IMO.

这就是该数字的来源。您看到的 17 是将从输出长度中减去多少个空格。长话短说,它将简单明了地确保每个输出都在同一个地方开始和结束。唯一的问题是,确保数字 22 比最大可能的字符串长。我看到最长的可能是Queen of Diamonds任何大于 19 的都应该做,我选择了 22 因为它在 IMO 看起来更好。

Next is the letter, that letter, as you can see, changes between the 2 output statements. In this case, one says s, the other says d. Easy way to solve this is, if your output is a String, use s, if it's and int (I don't think you will need it, I just had to for my example cuz mine were ints), use d.

接下来是字母,如您所见,该字母在 2 个输出语句之间发生变化。在这种情况下,一个说 s,另一个说 d。解决这个问题的简单方法是,如果您的输出是字符串,请使用 s,如果它是和 int(我认为您不需要它,我只需要在我的示例中使用 int),请使用 d。