问题
I have a very weird problem. After writing this:
for (File f : currentFile.listFiles()) {
if (f.isDirectory()){
System.out.println(f.getName()+"\t"+"Dir\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
else{
System.out.println(f.getName()+"\t"+"File\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
I see this printed:
see.txt File rw 267642728448
see1.txt File rw 267642728456
see2.txt File rw 267642728448
Why is there a problem with the tabs?
回答1:
Building on this question, I use the following code to indent my messages:
String prefix1 = "short text:";
String prefix2 = "looooooooooooooong text:";
String msg = "indented";
/*
* The second string begins after 40 characters. The dash means that the
* first string is left-justified.
*/
String format = "%-40s%s%n";
System.out.printf(format, prefix1, msg);
System.out.printf(format, prefix2, msg);
This is the output:
short text: indented looooooooooooooong text: indented
This is documented in section "Flag characters" in man 3 printf.
回答2:
The "problem" with the tabs is that they indent the text to fixed tab positions, typically multiples of 4 or 8 characters (depending on the console or editor displaying them). Your first filename is 7 chars, so the next tab stop after its end is at position 8. Your subsequent filenames however are 8 chars long, so the next tab stop is at position 12.
If you want to ensure that columns get nicely indented at the same position, you need to take into account the actual length of previous columns, and either modify the number of following tabs, or pad with the required number of spaces instead. The latter can be achieved using e.g. System.out.printf with an appropriate format specification (e.g. "%1$13s"
specifies a minimum width of 13 characters for displaying the first argument as a string).
回答3:
The length of the text that you are providing in each line is different, this is the problem, so if the second word is too long (see2.txt
is long 8 char which corresponds to a single tab lenght) it prints out a tab which goes to the next tabulation point.
One way to solve it is to programmatically add a pad to the f.getName()
text so each text generated: see.txt
or see2.txt
has the same lenght (for example see.txt_
and see2.txt
) so each tab automatically goes to the same tabulation point.
If you are developing with JDK 1.5 you can solve this using java.util.Formatter:
String format = "%-20s %5d\n";
System.out.format(format, "test", 1);
System.out.format(format, "test2", 20);
System.out.format(format, "test3", 5000);
this example will give you this print:
test 1
test2 20
test3 5000
回答4:
In continuation of the comments by Péter and duncan, I normally use a quick padding method, something like -
public String rpad(String inStr, int finalLength)
{
return (inStr + " " // typically a sufficient length spaces string.
).substring(0, finalLength);
}
similarly you can have a lpad()
as well
回答5:
The problem is the length of the filenames. The first filename is only 7 chars long, so the tab occurs at char 8 (doing a tab after every 4 characters). However the next filenames are 8 chars long, so the next tab won't be until char 12. And if you had filenames longer than 11 chars, you'd run into the same problem again.
回答6:
As mentioned by other folks, the variable length of the string is the issue.
Rather than reinventing the wheel, Apache Commons has a nice, clean solution for this in StringUtils.
StringUtils.rightPad("String to extend",100); //100 is the length you want to pad out to.
回答7:
You can also pad a string to the required length using Guava's Strings.padEnd(String input, int minLength, char padding)
回答8:
You can use this example to handle your problem:
System.out.printf( "%-15s %15s %n", "name", "lastname");
System.out.printf( "%-15s %15s %n", "Bill", "Smith");
You can play with the "%" until you find the right alignment to satisfy your needs
来源:https://stackoverflow.com/questions/6000810/printing-with-t-tabs-does-not-result-in-aligned-columns