32

I'm just trying to convert some C code over to Java and I'm having a little trouble with String.printf.

In C, to get a specific width based on a variable, I can use:

printf("Current index = %*d\n", sz, index);

and it will format the integer to be a specific size based on sz.

Trying:

System.out.println(String.format("Current index = %*d\n", sz, index));

results in an error since it doesn't like the *.

I currently have the following kludge:

System.out.println(String.format("Current index = %" + sz + "d\n", index));

but I'm hoping there's a slightly better way, yes?

1
  • Using println(String.format) is redundant. You should use printf method. Commented Aug 19, 2016 at 18:30

4 Answers 4

34

Declare an extra variable before using printf:

String format = "%" + fieldSize + "d";
System.out.printf(format, yourVariables);

(this is the first solution I found from a web search)

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

3 Comments

This is basically the same way he has done, except you're doing the same thing in two lines.
I’m sorry, I don’t see how this answer is useful, as it adds exactly nothing to the question.
Using a temporary variable circumvents an inspection warning in IntelliJ and is therefore better than OP's version
2

This is arguably no better than your "kludge", but here's a method you can embed into the call to printf that will substitute widths for the asterisks that you pass to it. Its result is used as the real format. For example, consider this call:

System.out.printf("%04d %2s %-7d;%n", 65, "a", 6);

I will replace the first and third widths via an embedded function:

System.out.printf( wf("%0*d %2s %-*d;%n", 4, 7), 65, "a", 6);

And here's the code:

public static String wf(String fmt, int... widths) {
    return metaWidthFormat('*', fmt, widths);
}

public static String metaWidthFormat(char wmeta, String fmt, int ... widths) {
    if (fmt == null) return null;
    int wix = 0;
    boolean outside = true;
    // initial capacity is sufficient for each substituted width to be 2 digs
    StringBuilder result = new StringBuilder(fmt.length() + widths.length);
    for (char ch : fmt.toCharArray()) {
        if (outside) {
            result.append(ch);
            outside = (ch != '%');
        } else {
            if (ch == wmeta) {
                result.append(widths[wix++]);
            } else {
                result.append(ch);
            }
            outside = (ch == wmeta) || (ch == '%') || Character.isAlphabetic(ch);
        }
    }
    return result.toString();
}

Comments

0

Presuming that index fits inside sz you can do something like:

char[] temp = new char[sz];
Arrays.fill(temp, '0');
DecimalFormat df = new DecimalFormat(new String(temp));
System.out.println(String.format("Current index = %s\n", df.format(index))); 

Note, by not using Format or any of its subclasses, there is no Locale dependent characters like ' ', '.' or ',' added to the output.

Comments

-1

maybe it's too late but putting it here for others

int width = 5;
int precision = 2;
float f = 12.34567f;
System.out.printf("%"+width+"."+precision+"f%n",f);

tested in java 1.8

2 Comments

@tilde not exactly, please take some time comparing difference
No, not exactly. You also set the precision. But the substance is the same - first, define the format string with +, then pass it to printf.

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.