printable char in java - java

Does anyone knows how to detect printable characters in java?
After a while ( trial/error ) I get to this method:
public boolean isPrintableChar( char c ) {
Character.UnicodeBlock block = Character.UnicodeBlock.of( c );
return (!Character.isISOControl(c)) &&
c != KeyEvent.CHAR_UNDEFINED &&
block != null &&
block != Character.UnicodeBlock.SPECIALS;
}
I'm getting the input via KeyListener and come Ctr-'key' printed an square. With this function seems fairly enough.
Am I missing some char here?

It seems this was the "Font" independent way.
public boolean isPrintableChar( char c ) {
Character.UnicodeBlock block = Character.UnicodeBlock.of( c );
return (!Character.isISOControl(c)) &&
c != KeyEvent.CHAR_UNDEFINED &&
block != null &&
block != Character.UnicodeBlock.SPECIALS;
}

I'm not perfectly sure whether I understand your problem. But if you want detect if character can be drawn to Graphics object, and if not print some placeholder char you might find usefull:
Font.canDisplay(int)
It will check whether font can display specific codepoint (it is more that check whether font is displayable at all -- since there are chars that are displayable - like ą - but some fonts cant display them.

Related

Confused on how to use || and && in the same if statement. Can anyone spot the problem?

I am confused on how to use || and && in the same if statement.
What I am trying to do is have it print something if the string starts with an "D" or an "O", and if one is true check if the string has a character length of two.
Example: if the string is "DE" it will print something. However, if it is "SE" it will not print anything.
else if( (answer.startsWith("D") || answer.startsWith("O"))
&& (answer.length() == 2) ) {
//print something
}
Java is applying a "short circuit" to your logic. It does the first part (starts with "D" or "O") and if that's true it proceeds to the second part (length is 2). However if the first part evaluates to false then it never even bothers to execute the second part.
So your "SE" string will never go into the "print something" bit because it doesn't meet your first criteria of starting with D or O. And based on your description of what the logic should be, that is correct.
If you actually mean that if it starts with "D" or "O" OR is 2 characters long then your logic statement should have been:
else if( answer.startsWith("D") || answer.startsWith("O")
|| (answer.length() == 2 ) {
//print something
}
Edit: Oops, just pasted the original code in the first time...!
I would check first the length and after the two conditions e.g.
else if (answer.lenght()==2) {
if (answer.startsWith("D") || answer.startsWith("O"){
//print something that lenght is 2 and starts with D or O
}
}
}
In that case you have to check length first because && will true if left side and right side both true
else if( (answer.length() == 2)&&(answer.startsWith("D") || answer.startsWith("O"))
{
//your logic
}

Reading from InputStream - stuck in cycle

I have this piece of code:
(this code is inside another cycle, that is cycling 3 times)
...
text = "";
while((c = is.read())!=-1){
if(prev == '\r' && c == '\n'){
break;
}
text = text + (char) c;
prev = (char) c;
}
System.out.println(text);
...
is is InputStream, c is int, prev is char
With this code I build up a string from the InputStream. The reading should stop everytime when I get \r\n. Then it start's over again. Everything works fine except one thing. The stream I get looks like this:
1233\r\n544\r\nX
There is no delimeter after this input stream
With this I get the string 1233 from the first cycle and string 544 from the second cycle. But I won't get the last X, because the cycle won't stop there - and I don't know why. I thought that with is.read()=!-1 the cycle should stop when the stream ends. But it doesn't. The program is stuck inside that cycle.
Your question is unclear but here goes:
while( ( c = is.read() ) != -1 )
{
if(prev == '\r' && c == '\n')
{
break;
}
text = text + (char) c;
prev = (char) c;
}
Notice the order of execution. Check for \r\n and exit loop then append current character to text.
Do you see anything wrong with this logic?
Also you said
the cycle should stop when the stream ends. But it doesn't. The
program is stuck inside that cycle.
If the last two bytes are never \r\n or if the stream never closes it will never end and it will drop the last \n either way!
So which is it the loop never ends or the \n never gets appended?
If you want the loop to end at the end of the stream and at when a \r\n is detected you need to re-order your logic.
Garbage In Garbage Out:
Assuming that there are actually \r\n pairs in your InputStream. Are you sure they are there?, Step debugging would tell you for certain!
public static void main(final String[] args)
{
final InputStream is = System.in;
final StringBuilder sb = new StringBuilder(1024);
try
{
int i;
while ((i = is.read()) >= 0)
{
sb.append((char)i);
if (sb.substring(sb.length()-2).equals("\r\n"))
{
break;
}
}
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
System.out.print(sb.toString());
}
You need to stop and learn how to use the step debugger that is in
your IDE. This would not be a question if you just stepped through
your code and put a few break points where things were not as you
wanted or expected them.

Java && operators

I'm trying to make simple if statement , I need to see if my two String's values are not empty (does not equal "").
I use && operator , but sadly , it only checks one string properly if it's not empty , and if the second string is empty, he passes . Making && kinda useless for me.
if ( StringUtils.isNullOrEmpty(name) && StringUtils.isNullOrEmpty(sname)
) {do something}
I need them both to be checked properly . If at least one string is empty return false .
If both are not empty return true.
Currently your condition is true if both Strings are null or empty.
If you want both not to be null or empty you need :
if ( !StringUtils.isNullOrEmpty(name) && !StringUtils.isNullOrEmpty(sname)
) {do something}
&& is smart and if first condition is false it doesn't try the second.
use & could achieve what you want.
The problem is that your check is wrong. You want it to only pass if both ARE empty.
So you should go for
if ( !StringUtils.isNullOrEmpty(name) && !StringUtils.isNullOrEmpty(sname)
) {do something}
or if u want to catch it in the if statement if one of them IS empty, you should use or:
if ( StringUtils.isNullOrEmpty(name)|| StringUtils.isNullOrEmpty(sname)
) {do something}
isNullOrEmpty will return true if name is empty, but you want it NOT empty, so negate the conditions using !.
if ( !StringUtils.isNullOrEmpty(name) && !StringUtils.isNullOrEmpty(sname)
) {do something}
Another alternative is:
if (!(StringUtils.isNullOrEmpty(name) || StringUtils.isNullOrEmpty(sname)
)) {do something}
However, the above is not a recommended coding style, as it is difficult to catch the ! hidden just before the line, and code readers may get confused.
About || and && operators optimized checking:
|| checks for the first true condition from left to right and skips any further checking if it finds one true condition.
&& checks for the first false condition from left to right and skips any further checking if it finds one false condition.
At first it didn't looked any sense to me , and it didn't worked . Only then I realized that I need to to flip the return statements.
if (!StringUtils.isNullOrEmpty(name) && !StringUtils.isNullOrEmpty(sname)) {
System.out.println("ok");
return true;}
else {
System.out.println("empty names");
return false;
}
Now it seems to work just fine.
Using '&' as logical operator you can do the following thing. Here we have not use StringUtils -
if( ( null!=name && !name.isEmpty() ) &
( null!=sname && !sname.isEmpty() ) ){do something}

String not populating properly

I am writing a program that is going to read a string from a file, and then remove anything that isn't 1-9 or A-Z or a-z. The A-Z values need to become lowercase. Everything seems to run fine, I have no errors, however my output is messed up. It seems to skip certain characters for no reason whatsoever. I've looked at it and tweaked it but nothing works. Can't figure out why it is randomly skipping certain characters because I believe my if statements are correct. Here is the code:
String dataIn;
int temp;
String newstring= "";
BufferedReader file = new BufferedReader(new FileReader("palDataIn.txt"));
while((dataIn=file.readLine())!=null)
{
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
i++;
}
System.out.println(newstring);
}
So to give you an example, the first string I read in is :
A sample line this is.
The output after my program runs through it is this:
asmlietis
So it is reading the A making it lowercase, skips the space like it is suppose to, reads the s in, but then for some reason skips the "a" and the "m" and goes to the "p".
You're incrementing i in the each of the blocks as well as in the main loop "header". Indeed, because you've got one i++; in an else statement for the last if statement, you're sometimes incrementing i twice during the loop.
Just get rid of all the i++; statements other than the one in the for statement declaration. For example:
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
}
I wouldn't stop editing there though. I'd also:
Use a char instead of an int as the local variable for the current character you're looking at
Use character literals for comparisons, to make it much clearer what's going on
Use a StringBuilder to build up the string
Declare the variable for the output string for the current line within the loop
Use if / else if to make it clear you're only expecting to go into one branch
Combine the two paths that both append the character as-is
Fix the condition for numbers (it's incorrect at the moment)
Use more whitespace for clarity
Specify a locale in toLower to avoid "the Turkey problem" with I
So:
String line;
while((line = file.readLine()) != null)
{
StringBuilder builder = new StringBuilder(line.length());
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
// Are you sure you want to trim 0?
if ((current >= '1' && current <= '9') ||
(current >= 'a' && current <= 'z')) {
builder.append(current);
} else if (current >= 'A' && current <= 'Z') {
builder.append(Character.toLowerCase(current, Locale.US));
}
}
System.out.println(builder);
}

Problem with underscore(_) in Collections.binarySearch (Java)

Problem:
I am using Java Tutorials™ sourcecode for this. This is the source code.
I tried this:
--following with another section of sorted words--
words.add("count");
words.add("cvs");
words.add("dce");
words.add("depth");
--following with another section of sorted words--
and it works perfectly. However when I use this:
--just a section of sorted words--
words.add("count");
words.add("cvs");
words.add("dce_iface");
words.add("dce_opnum");
words.add("dce_stub_data");
words.add("depth");
--following with another section of sorted words--
It does show dce_iface when I type dce, but when I type _ then following with o or s it shows me something else like dce_offset where the offset comes from words.add("fragoffset"); somewhere in the list.
What can I do to solve this problem? Thank you in advance.
It's probably because of these lines in the code:
for (w = pos; w >= 0; w--) {
if (! Character.isLetter(content.charAt(w))) {
break;
}
}
_ is not a letter character, so it treats it the same way as a space. You can try changing the condition to:
char c = content.charAt(w);
if (! (Character.isLetter(c) || c == '_')) {
I guess you have to add the underscore as "letter" here
// Find where the word starts
int w;
for (w = pos; w >= 0; w--) {
if (!Character.isLetter(content.charAt(w))) {
break;
}
}
It has to do with this section in insertUpdate():
// Find where the word starts
int w;
for (w = pos; w >= 0; w--) {
if (! Character.isLetter(content.charAt(w))) {
break;
}
}
Specifically, Character.isLetter() returns false for the underscore character. That means that the word starts after the underscore position.
To solve it, you need to modify the if statement to allow any non letter characters you want to use in the words. You could explicitly check for '_' or use Chacter.isWhiteSpace() to include all characters that aren't a space, tab or newline.

Categories

Resources