Question

On Java, I know that the next thing is ok:

String test="aaa";
System.out.println(String.format(test,"asd"));

(prints "aaa")

However, I want to be able to handle the opposite thing, such as:

String test="aaa%sbbb";
System.out.println(String.format(test));

(this produces an exception java.util.MissingFormatArgumentException )

I wish to make it as general as possible, no matter how many specifiers/parameters are there, if there aren't enough values, just ignore them (skip all of the specifiers from the problematic position) and write the rest of the string (in the case I've shown, for example, it will write "aaabbb" ) .

Is it possible out of the box, or should I write a function that does it?

Was it helpful?

Solution

ok, i think i've got a working solution, and i also think it supports everything that String.format supports:

public static String formatString(final String stringToFormat,final Object... args)
  {
  if(stringToFormat==null||stringToFormat.length()==0)
    return stringToFormat;
  int specifiersCount=0;
  final int argsCount=args==null ? 0 : args.length;
  final StringBuilder sb=new StringBuilder(stringToFormat.length());
  for(int i=0;i<stringToFormat.length();++i)
    {
    char c=stringToFormat.charAt(i);
    if(c!='%')
      sb.append(c);
    else
      {
      final char nextChar=stringToFormat.charAt(i+1);
      if(nextChar=='%'||nextChar=='n')
        {
        ++i;
        sb.append(c);
        sb.append(nextChar);
        continue;
        }
      // found a specifier
      ++specifiersCount;
      if(specifiersCount<=argsCount)
        sb.append(c);
      else while(true)
        {
        ++i;
        c=stringToFormat.charAt(i);
        // find the end of the converter, to ignore it all
        if(c=='t'||c=='T')
          {
          // time prefix and then a character, so skip it
          ++i;
          break;
          }
        if(c>='a'&&c<='z'||c>='A'&&c<='Z')
          break;
        }
      }
    }
  return String.format(sb.toString(),args);
  }

and a test, just to show it works:

System.out.println(formatString("aaa%sbbb"));
System.out.println(formatString("%da%sb%fc%tBd%-15se%16sf%10.2fg"));

sadly, it creates a new stringBuilder and a string on the way, but it works.

OTHER TIPS

Is it possible out of the box, or should I write a function that does it?

It is not possible out of the box. There is nothing in the standard implementation for ignoring this.

I guess you could write a function that processes the format string to get rid of "unwanted" format specifiers. But it would most likely be easier to either:

  • choose or generate the format string based on the number of arguments you have,
  • call the format method once for each argument, or
  • do the formatting some other way entirely.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top