2

I've been asked to create a program that takes items from a text file and displays them in a list formatted "LastName, FirstName ZipCode" where the ZIP codes all align on the right and the Last and First names are only separated by a comma and a space.

I'm having no problem getting everything to list, the only problem I'm running into is aligning the ZIP codes.

Currently this is what I have written for the output format:

System.out.printf("%s, %s %s\n", fileList.get(lastName), fileList.get(i), fileList.get(zipCode));

And my output is this (as expected):

Baron, Steven 84521
Chill, Robert 63258
Blanthony, Stacy 84815
Wick, John 78412
Yule, Katherine 42136

(etc)

Here's how I want it to look:

Baron, Steven    84521
Chill, Robert    63258
Blanthony, Stacy 84815
Wick, John       78412
Yule, Katherine  42136

I was thinking maybe I could do something where I count the total number of characters from the LastName all the way to the ZIP code and then have that subtracted from a very large number of spaces between the LastName and ZipCode, but I wasn't sure how to do that since it would be bouncing between Strings and Ints. Also, I imagine there is a much simpler solution that I'm just not aware of.

Any help is appreciated!

Thank you,

CCoolant

CCoolant
  • 41
  • 1
  • 5
  • See the docs: http://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html – Usagi Miyamoto Sep 10 '17 at 20:53
  • Possible duplicate of [Align printf output in Java](https://stackoverflow.com/questions/15961130/align-printf-output-in-java) – blipman17 Sep 10 '17 at 21:07
  • I looked at the question posted by user1781482, but didn't understand how that would help to right-justify my column. Also looked through the Formatter doc, and I don't understand how I can use that to achieve what I want, could you explain further? – CCoolant Sep 10 '17 at 21:19
  • Can you update the question with an example of how you want it to look? – NickL Sep 10 '17 at 21:22
  • Sorry about that! Just edited the question. – CCoolant Sep 10 '17 at 21:25

2 Answers2

2

Got word back on this one and got an answer that may help others in the future! This depends on setting up the arrays used in a different way, but hopefully this will be of some help nonetheless. By concatenating the first and last name like so:

String lastNameAndFirstName = (lastName + ", " + firstName);

You can control the total width of both of these variables by making them a single column of a width determined by you. So instead of managing three columns you can use just the two and do something like:

System.out.printf(%-20s %s, lastNameAndFirstName, zipCode);

This should give you something like the example list I presented above:

Baron, Steven    84521
Chill, Robert    63258
Blanthony, Stacy 84815
Wick, John       78412
Yule, Katherine  42136

This way the names on the left are left-justified (which looks nice) and the numbers on the right will be right-justified.

Hopefully someone else finds this of use! :)

CCoolant
  • 41
  • 1
  • 5
1

There's a couple of options, depending on how much you care about the result, and what behavior you're looking for.

  • An easy choice is to just tab-delimit, e.g. System.out.printf("%s\t%s\n", foo, bar);

    Most consoles will align tabs in 8-column increments, so as long as the foo values are a similar length you'll get nicely separated results, though they are still left-justified and may sometimes end up with individual rows that aren't aligned, e.g your data would look like this (I used spaces to ensure consistent display, pretend they're tabs):

    Baron, Steven   84521
    Chill, Robert   63258
    Blanthony, Stacy        84815
    Wick, John      78412
    Yule, Katherine 42136
    

    Benefits: easy to write, easy for a machine to parse (it's TSV data).

    Cons: not necessarily easy for a person to read, since different-width columns don't line up.

  • As suggested in the comments the formatter syntax supports right-justification by specifying the [width] of the field, e.g. System.out.printf("%s %10s\n", foo, bar) will ensure the field is at least 10 characters wide. This works well if you know the maximum width of the field in advance, or are able to do a pass over the data first to compute it.

    Benefits: right-justified. This is probably what you want.

    Cons: need to know how wide your data is or it will overflow and look about as bad as the tab solution.

  • Use Guava's Strings.padStart() or a similar utility to pad all the strings to the same width. This is basically just the manual equivalent of the formatter's width option, but in some cases this may make more sense (e.g. if you're dynamically computing the desired width).

    Benefits: more flexible than the formatter, e.g. if the target width is determined at runtime.

    Cons: more manual than the formatter :)

  • Determine the console width of your terminal, and compute the amount of space needed to actually right-justify the text along the right-hand side of the screen. That's consoleWidth - foo.length() - bar.length(). There are several ways to determine the console width, none of which are perfect.

    Benefits: actually right-justified, looks really nice

    Cons: tricky to get right, likely more trouble than it's worth :)

dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Thank you very much for the detailed answer! I'll experiment with these solutions and see what I can get. : ) – CCoolant Sep 10 '17 at 23:01