Variable widths in Java's String.format method - java

I'm working on a project in which I need to display textual trees. I'm trying to use Java's String.format method to simplify the formatting process, but I ran into trouble when trying to apply variable widths.
Current I have a variable (an int) which is called depth.
I try to do the following:
String.format("%"+depth+"s"," ") + getOriginalText() + "\n";
However I get the following error.
java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
Any suggestions on how to do this, or should I just settle for loops?
Thanks for the help!

This works:
int depth = 5;
String str= "Hello"+ String.format("%"+depth+"s"," ") + "world" + "\n";
System.out.println(str);
It prints 5 while spaces in between.
Hello World.
Please check you code and make sure that depth is assigned with a valid int value. Most likely that (invalid value in depth) is the problem.

You could try the following using "System.out.printf" command:
int depth = 10;
System.out.printf("%s" + "%" +depth + "s", "Hello","World" );
Hello    World

Related

Why do we print variable values like this?

I want to know why we concatenate a dummy string with a variable while printing its value.
Eg.
system.out.print(var + " ");
Concatenation with an empty string is a technique some developers use to convert any value to a string. It's unnecessary with System.out.print as that accepts any value anyway. I prefer using String.valueOf anyway:
String text = String.valueOf(variable);
This is clearer in terms of the purpose being converting a value to a string, rather than concatenation.
However, in the case you've given, it's possible that the developer wasn't just using concatenation for that purpose - but actually to get the extra space. For example:
int var1 = 1, var2 = 2, var3 = 3;
System.out.print(var1 + " ");
System.out.print(var2 + " ");
System.out.print(var3 + " ");
Those will all print on the same line:
1 2 3
Other options include:
Using a StringBuilder to build up the string before printing it
Putting it all into a single System.out.print call: System.out.print(var1 + " " + var2 + " " + var3);
Using printf instead: System.out.printf("%d %d %d", var1, var2, var3);
Extremely sorry. The question was l1.setText(var+" "); and it is done because a text field cannot take an integer value, so we concatenate a dummy string at the end of it, so the integer value in var can be printed.
Thank you all for helping me out!

Split String to String[] by a period but returning an empty array

Ok maybe i just need a second pair of eyes on this.
I have a float, that I turn into a string. I then want to split it by its period/decimal in order to present it as a currency.
Heres my code:
float price = new Float("3.76545");
String itemsPrice = "" + price;
if (itemsPrice.contains(".")){
String[] breakByDecimal = itemsPrice.split(".");
System.out.println(itemsPrice + "||" + breakByDecimal.length);
if (breakByDecimal[1].length() > 2){
itemsPrice = breakByDecimal[0] + "." + breakByDecimal[1].substring(0, 2);
} else if (breakByDecimal[1].length() == 1){
itemsPrice = breakByDecimal[0] + "." + breakByDecimal[1] + "0";
}
}
If you take this and run it, you will get an array index out of bounds error on line 6 (in the code above) regarding there being nothing after a decimal.
In fact on line 5, when i print out the size of the array, it's 0.
These are to ridiculous of errors for them to NOT be something i am simply overlooking.
Like I said, another pair of eyes is exactly what i need, so please don't be rude when pointing out something that's obvious to you but I overlooked it.
Thanks in advance!
split uses regular expressions, in which "." means match any character. you need to do
"\\."
EDIT: fixed, thanks commenter&editor
Use decimal format instead:
DecimalFormat formater = new DecimalFormat("#.##");
System.out.println(formater.format(new Float("3.76545")));
I have not worked much on java, but on line 2, maybe price is not getting converted to string.
I work in C# and I would use that as :
String itemsPrice = "" + price.ToString();
maybe you should convert price to string first explicitly.
Since, it is not getting converted, string only contains "" and there is no ".", so no split and by extension arrayOutOfBounds error.
If you want to present it as a price use NumberFormat.
Float price = 3.76545;
Currency currency = Currency.getInstance(YOUR_CURRENCY_STRING);
NumberFormat numFormat = NumberFormat.getCurrencyInstance();
numFormat.setCurrency(currency)
numFormat.setMaximumFractionDigits(currency.getDefaultFractionDigits());
String priceFormatted = numFormat.format(price);
System.out.println("The price is: " + priceFormatted);
YOUR_CURRENCY_STRING is the ISO 4217 currency code for the currency you are dealing with.
Also, it's generally a bad idea to represent prices in a non-precise format (such as floating point). You should use BigDecimal or Decimal.
If you want to handle it all by yourself then try the following code:
public static float truncate(float n, int decimalDigits) {
float multiplier = (float)Math.pow(10.0,decimalDigits);
int intp = (int)(n*multiplier);
return (float)(intp/multiplier);
}
and get the truncatedPrice like this:
float truncatedPrice = truncate(3.3654f,2);
System.out.println("Truncated to 2 digits : " + truncatedPrice);

Print multiple lines output in java without using a new line character

this is one of the interview question. I am supposed to print multiple lines of output on command line, without using the newline(\n) character in java. I tried googling for this, didn't find appropriate answers. If i am printing 5 numbers, then it should print in the following fashion. But I am not supposed to use the newline character nor loops either. I have to print this using a single println() statement. Can you give me some ideas ? Thanks !
1
2
3
4
5
You can do it recursively:
public void foo(int currNum) {
if (currNum > 5)
return;
println(currNum);
foo(currNum + 1);
}
Then you are only using a single println and you aren't using a for or while loop.
If you're just not allowed of using \n and println() then you can get the systems line.separator, e.g.
String h = "Hello" + System.getProperty("line.separator") + "World!"
Hope this helped, have Fun!
Ok, now I think I understand your question. What about this?
println(String.format("%d%n%d%n%d%n%d%n%d%n", 1, 2, 3, 4, 5));
One way is this: Platform Independent
final String EOL = System.getProperty("line.separator");
System.out.println('1' + EOL + '2' + EOL + '3' + EOL + '4' + EOL + '5');
This is Platform Dependent
char eol = (char) 13;
System.out.println("" + '1' + eol + '2' + eol + '3' + eol + '4');
There are many ways to achieve this...
One alternative to using '\n' is to output the byte value for the character. So, an example to print out your list of the numbers 1-5 in your example...
char line = (char)10;
System.out.println("1" + line+ "2" + line+ "3" + line + "4" + line+ "5");
You could also build a byte[] array or char[] array and output that...
char line = (char)10;
char[] output = new char[9]{'1',line,'2',line,'3',line,'4',line,'5'};
System.out.println(new String(output));
Probably cheating based on the requirements, but technically only 1 println statement and no loops.
public int recursivePrint(int number)
{
if (number >=5 )
return number;
else
System.out.println(recursivePrint(number++));
}
No loops, 1 println call, +flexibility:
public static void main (String[] args) {
print(5);
}
final String newLine = System.getProperty("line.separator");
public void print(int fin) {
System.out.println(printRec("",1,fin));
}
private String printRec(String s, int start, int fin) {
if(start > fin)
return s;
s += start + newLine;
return printRec(s, start+1, fin);
}
The ASCII value of new Line is 10.
So use this
char line = 10;
System.out.print("1" + line + "2" + line ......);
ANSI terminal escape codes can do the trick.
Aside: Since System.out is a PrintStream, it may not be able to support the escape codes.
However, you can define your own println(msg) function, and make one call to that. Might be cheating, but unless they explicitly say System.out.println, you're golden (hell, even if they do, you can define your own object named System in the local scope using a class defined outside your function, give it a field out with a function println(msg) and you're still scot-free).

How do you parse non-standard form function?

A standard form function like A*B+A*B' is easy to parse (spliting by + and then spliting by *). How do you parse a function, if it doesn't take a standard form?
Example: a function can take the following forms:
A*B+A(A+B')
A*B+(A+B')A
A*B+A*B(A+B)
Any ideas?
P.S: I would like to parse the function in Java.
A standard form function like A*B+A*B' is easy to parse (splitting by + and then splitting by *).
Good. Now, all that's left is to deal with those pesky parenthesis. First, we will remove them with array.split, and then we will add the necessary logic to carry out the multiplications:
Once you have split the string A(A+B')C, you will end up with an array of three strings A, A+B, and C. And notice that in this method odd-number strings are ALWAYS the ones inside the parenthesis. So all we have to do is check to see if the last and first characters of odd strings are letters (A, B, C) or operators (*,+).
String firstString = "A*B+A*B(A+B)+A*B+A*B(A+B)";
String leftOfParenthesis;
String insideParenthesis;
String rightOfParenthesis
String last;
String first;
String[] masterArray;
masterArray = str.split(firstString);
for(int i=0; i<masterArray.length; i+2){
leftOfParenthesis = masterArray[i];
insideParenthesis = masterArray[i+1];
rightParenthesis = masterArray[i+2];
last = leftOfParenthesis.substring(leftOfParenthesis.length()-1);
first = rightParenthesis.substring(0,1);
if(last.isLetter() && first.isLetter()){
leftOfParenthesis.append("*" + insideParenthesis + "*" +
last + "+last*" + insideParenthesis + "*" + first);
rightOfParenthesis[0] = last;
}
else if(last.isLetter()){
leftOfParenthesis.append("*" + insideParenthesis + "*" + last);
}
else if(first.isLetter()){
leftOfParenthesis.append("+" + first + "*" +
insideParenthesis + "*" );
}
}
That's the basic logic. There will be some issues with the rightParenthesis = masterArray[i+2]; if you run past the end of your input string and there aren't that many terms left. So you will have to add some if statements to check for that. And this isn't totally generally, if you have parenthesis inside parenthesis or more than two terms inside a pair of parenthesis, you will have to add special logic to deal with that.
Rather than trying to parse with ad hoc methods (which always ends badly), you
are better off
writing an BNF grammar for your expression forms, in all
variants
code a recursive descent parser (See
https://stackoverflow.com/a/2336769/120163)

Help building a regex

I need to build a regular expression that finds the word "int" only if it's not part of some string.
I want to find whether int is used in the code. (not in some string, only in regular code)
Example:
int i; // the regex should find this one.
String example = "int i"; // the regex should ignore this line.
logger.i("int"); // the regex should ignore this line.
logger.i("int") + int.toString(); // the regex should find this one (because of the second int)
thanks!
It's not going to be bullet-proof, but this works for all your test cases:
(?<=^([^"]*|[^"]*"[^"]*"[^"]*))\bint\b(?=([^"]*|[^"]*"[^"]*"[^"]*)$)
It does a look behind and look ahead to assert that there's either none or two preceding/following quotes "
Here's the code in java with the output:
String regex = "(?<=^([^\"]*|[^\"]*\"[^\"]*\"[^\"]*))\\bint\\b(?=([^\"]*|[^\"]*\"[^\"]*\"[^\"]*)$)";
System.out.println(regex);
String[] tests = new String[] {
"int i;",
"String example = \"int i\";",
"logger.i(\"int\");",
"logger.i(\"int\") + int.toString();" };
for (String test : tests) {
System.out.println(test.matches("^.*" + regex + ".*$") + ": " + test);
}
Output (included regex so you can read it without all those \ escapes):
(?<=^([^"]*|[^"]*"[^"]*"[^"]*))\bint\b(?=([^"]*|[^"]*"[^"]*"[^"]*)$)
true: int i;
false: String example = "int i";
false: logger.i("int");
true: logger.i("int") + int.toString();
Using a regex is never going to be 100% accurate - you need a language parser. Consider escaped quotes in Strings "foo\"bar", in-line comments /* foo " bar */, etc.
Not exactly sure what your complete requirements are but
$\s*\bint\b
perhaps
Assuming input will be each line,
^int\s[\$_a-bA-B\;]*$
it follows basic variable naming rules :)
If you think to parse code and search isolated int word, this works:
(^int|[\(\ \;,]int)
You can use it to find int that in code can be only preceded by space, comma, ";" and left parenthesis or be the first word of line.
You can try it here and enhance it http://www.regextester.com/
PS: this works in all your test cases.
$[^"]*\bint\b
should work. I can't think of a situation where you can use a valid int identifier after the character '"'.
Of course this only applies if the code is limited to one statement per line.

Categories

Resources