329

I am trying to use a .format method of a string. But if I place %1, %2, etc. in the string, java.util.UnknownFormatConversionException is thrown pointing to a confusing Java source code piece:

private void checkText(String s) {

    int idx;

    // If there are any '%' in the given string, we got a bad format
    // specifier.
    if ((idx = s.indexOf('%')) != -1) {
        char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
        throw new UnknownFormatConversionException(String.valueOf(c));
    }
}

From this I understand that % char is forbidden. If so, then what should I use for argument placeholders?

I use Scala 2.8.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
Ivan
  • 63,011
  • 101
  • 250
  • 382

11 Answers11

304

While all the previous responses are correct, they're all in Java. Here's a Scala example:

val placeholder = "Hello %s, isn't %s cool?"
val formatted = placeholder.format("Ivan", "Scala")

I also have a blog post about making format like Python's % operator that might be useful.

Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
pr1001
  • 21,727
  • 17
  • 79
  • 125
  • 2
    A lot of examples in JDK documentation: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax – angelcervera Nov 27 '13 at 20:58
  • 1
    You can simplify by applying `format` directly to the string literal: `"Hello %s, isn't %s cool?".format("Ivan", "Scala")` – sotrh Aug 26 '14 at 18:57
299

You don't need to use numbers to indicate positioning. By default, the position of the argument is simply the order in which it appears in the string.

Here's an example of the proper way to use this:

String result = String.format("The format method is %s!", "great");
// result now equals  "The format method is great!".

You will always use a % followed by some other characters to let the method know how it should display the string. %s is probably the most common, and it just means that the argument should be treated as a string.

I won't list every option, but I'll give a few examples just to give you an idea:

// we can specify the # of decimals we want to show for a floating point:
String result = String.format("10 / 3 = %.2f", 10.0 / 3.0);
// result now equals  "10 / 3 = 3.33"

// we can add commas to long numbers:
result = String.format("Today we processed %,d transactions.", 1000000);
// result now equals  "Today we processed 1,000,000 transactions."

String.format just uses a java.util.Formatter, so for a full description of the options you can see the Formatter javadocs.

And, as BalusC mentions, you will see in the documentation that is possible to change the default argument ordering if you need to. However, probably the only time you'd need / want to do this is if you are using the same argument more than once.

TM.
  • 108,298
  • 33
  • 122
  • 127
128

Instead of looking at the source code, you should read the javadoc String.format() and Formatter syntax.

You specify the format of the value after the %. For instance for decimal integer it is d, and for String it is s:

String aString = "world";
int aInt = 20;
String.format("Hello, %s on line %d",  aString, aInt );

Output:

Hello, world on line 20

To do what you tried (use an argument index), you use: *n*$,

String.format("Line:%2$d. Value:%1$s. Result: Hello %1$s at line %2$d", aString, aInt );

Output:

Line:20. Value:world. Result: Hello world at line 20
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
70

You can use this;

String.format("%1$s %2$s %2$s %3$s", "a", "b", "c");

Output:

a b b c

Engin Ardıç
  • 2,459
  • 1
  • 21
  • 19
  • 1
    I have never seen this kind of useage, it's very useful when repeat string, great! – Domi.Zhang Nov 07 '13 at 05:48
  • 8
    +1 this is more like what you use as a C# developer. There, we use `{0}` and `{1}` instead of `%1$` and `%2$`. – ashes999 Nov 26 '13 at 02:36
  • @ashes999 I'm from c# land aswell. I'm so used to numbered brackets I'd forgotton that wasn't the standard way of doing things. Seeing the percent signs brings it all back though! – JonnyRaa May 12 '14 at 12:26
13

Also note that Scala extends String with a number of methods (via implicit conversion to a WrappedString brought in by Predef) so you could also do the following:

val formattedString = "Hello %s, isn't %s cool?".format("Ivan", "Scala")
denis phillips
  • 12,550
  • 5
  • 33
  • 47
11

The official reference is the class Formatter.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Alberto Segura
  • 755
  • 1
  • 12
  • 28
10

In Scala 2.10

val name = "Ivan"
val weather = "sunny"

s"Hello $name, it's $weather today!"
Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
Londo
  • 448
  • 4
  • 9
  • 1
    I take it that this is merely a special syntax of string concatenation (meaning that $name and $weather are hard references to the variables defined before). String.Format however takes the template as a parameter and thus makes it possible for example to retreive the template from a properties file and such. - Is that possible with the above syntax? – chiccodoro Dec 09 '13 at 09:25
  • It is call String interpolation, within scala there are two types: s"" and f"", the 's' is simple string and the 'f' is similar to the `printf`, you could even define your own interpolation (I haven't try). The `$name` means that it need to be replace with the value of the variable `name`, you could also do operation in the interpolation, for example `s"Hello ${name.toUpperCase}, it's $weather today!"` – Londo Apr 11 '14 at 16:33
4

This is a list of what String.format can do. The same goes for printf

int i = 123;
o.printf( "|%d|%d|%n" ,       i, -i );      // |123|-123|
o.printf( "|%5d|%5d|%n" ,     i, -i );      // |  123| –123|
o.printf( "|%-5d|%-5d|%n" ,   i, -i );      // |123  |-123 |
o.printf( "|%+-5d|%+-5d|%n" , i, -i );      // |+123 |-123 |
o.printf( "|%05d|%05d|%n%n",  i, -i );      // |00123|-0123|

o.printf( "|%X|%x|%n", 0xabc, 0xabc );      // |ABC|abc|
o.printf( "|%04x|%#x|%n%n", 0xabc, 0xabc ); // |0abc|0xabc|

double d = 12345.678;
o.printf( "|%f|%f|%n" ,         d, -d );    // |12345,678000|     |-12345,678000|
o.printf( "|%+f|%+f|%n" ,       d, -d );    // |+12345,678000| |-12345,678000|
o.printf( "|% f|% f|%n" ,       d, -d );    // | 12345,678000| |-12345,678000|
o.printf( "|%.2f|%.2f|%n" ,     d, -d );    // |12345,68| |-12345,68|
o.printf( "|%,.2f|%,.2f|%n" ,   d, -d );    // |12.345,68| |-12.345,68|
o.printf( "|%.2f|%(.2f|%n",     d, -d );    // |12345,68| |(12345,68)|
o.printf( "|%10.2f|%10.2f|%n" , d, -d );    // |  12345,68| | –12345,68|
o.printf( "|%010.2f|%010.2f|%n",d, -d );    // |0012345,68| |-012345,68|

String s = "Monsterbacke";
o.printf( "%n|%s|%n", s );                  // |Monsterbacke|
o.printf( "|%S|%n", s );                    // |MONSTERBACKE|
o.printf( "|%20s|%n", s );                  // |        Monsterbacke|
o.printf( "|%-20s|%n", s );                 // |Monsterbacke        |
o.printf( "|%7s|%n", s );                   // |Monsterbacke|
o.printf( "|%.7s|%n", s );                  // |Monster|
o.printf( "|%20.7s|%n", s );                // |             Monster|

Date t = new Date();
o.printf( "%tT%n", t );                     // 11:01:39
o.printf( "%tD%n", t );                     // 04/18/08
o.printf( "%1$te. %1$tb%n", t );            // 18. Apr
PRO_gramista
  • 922
  • 1
  • 9
  • 26
2

Here is a list of formatters used with String.format()

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html

NixRam
  • 509
  • 1
  • 10
  • 21
1

Although @Londo mentioned Scala's "s" string interpolator, I think Scala's "f" string interpolator is more relevant to the original question. The example used a few time in other responses could also be written (since Scala 2.10) this way:

scala> val name = "Ivan"
name: String = Ivan
scala> val thing = "Scala"
thing: String = Scala
scala> val formatted = f"Hello $name%s, isn't $thing%s cool?"
formatted: String = Hello Ivan, isn't Scala cool?

The connection to the original question is to be aware that:

  • formatted is defined with a string that is prefixed with the letter "f". This is the "f" (formatting) string interpolator.
  • The "f" string interpolator uses java.util.Formatter
  • java.lang.String.format uses the same java.util.Formatter

The nice thing about string interpolation is that it lets you see which variable is being substituted directly into the string instead of having to match it with the arguments to the String.format method.

Reid Spencer
  • 2,776
  • 28
  • 37
0

In scala , for string Interpolation we have $ that saves the day and make our life much easy:

For Example: You want to define a function that takes input name and age and says Hello With the name and says its age. That can be written like this:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is $age"

Hence , When you call this function: like this :

funcStringInterpolationDemo("Shivansh",22)

Its output would be :

Hey ! my name is Shivansh and my age is 22

You can write the code to change it in the same line, like if you want to add 10 years to the age !

then function could be :

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is ${age+10}"

And now the output would be :

Hey ! my name is Shivansh and my age is 32
Shivansh
  • 3,454
  • 23
  • 46