Java unable to read signed negative bytes written to standard out - java

I have 2 classes, the first is fed a binary string of 1s and 0s to standard in, and splits the string into sub strings of length 8 to convert to bytes, to write to standard out like so:
byte b = (byte)Integer.parseInt(byteString, 2);
System.out.write(b);
System.out.flush();
The second is piped the output of the first, and ultimately will turn the bytes back into the long binary string, but currently I have it just doing this:
int next;
while((next = System.in.read())!=-1){
System.out.print(next); System.out.print(" ");
System.out.flush();
}
If I replace System.out.write(b); with System.out.print(b); System.out.print(" "); in the first class with some small sample input, the output is -80 -84 83 11 98 -116 53 -119 49 27 10 -80 -72 104 -123 0
If I pipe this output to the second class it outputs 63 63 83 11 98 63 53 63 49 27 13 10 63 63 104 63 0 13 10
Two things seem to be happening that I can't figure out why, System.in.read() is returning 63, which is ASCII for ? when reading bytes that would be signed negative, and a carriage return + new line has been added to the end. I am stumped for solutions, insight is greatly appreciated.
Note: I was running this in Windows 10 powershell, but on normal command line and in a linux terminal the behaviour was as expected, so problem is only in powershell!

I do not use powershell, but a small test shows that pipes do change the output, like adding a newline and carriage return at the end, or converting the byte 0xA2 to 0x3f ('?').
Searching the net I found Understanding the Windows PowerShell Pipeline. I did not read more than the first paragraph, but that contains a hint:
Piping works virtually everywhere in Windows PowerShell. Although you see text on the screen, Windows PowerShell does not pipe text between commands. Instead, it pipes objects.
Maybe this helps: What exactly does the pipe | mean in PowerShell?

int next;
while((next = System.in.read())!=-1){
System.out.print(next); System.out.print(" ");
System.out.flush();
}
Bytes are signed in Java, and so is the result of InputStream.read(). Try this:
int next;
DataInputStream in = new DataInputStream(System.in);
for (;;)
{
try
{
next = in.readUnsignedByte();
System.out.print(next); System.out.print(" ");
System.out.flush();
}
catch (EOFException exc)
{
break;
}
}

Related

How to detect a newLine when there is only Carriage Return [13] without a LF aside

QUESTION EDITED
In my Java program my barcode reader reads some characters into a TextBox.
This string ends with [CR] char. In my listener I get KeyCode 77 M char for a [CR] but for [LF] I get 10 as expected.
How can I handle a newline to trigger enter operation when I get only [CR] without a [LF] and what is this 77 (M) ?
This is what I expect
This is what I get. CR is ASCII 13 but I get 77 (M char)
Normally in my barcode there is an actual M char and I don't want to handle 77 as enter.
My string ends with only CR but not LF . I think in Windows CR+LF makes a newline. My problem is without LF I can't handle CR. So I can't handle an enter.
Which component or listener should I use to handle just CR (decimal 13)? In a .NET app I can easily handle this[CR].
Here is my listener
textFieldSquareBarcode.addKeyListener(new java.awt.event.KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode()=='\r')
DO(); //!!!!
}
P.S.
CR is Carriage Return 13 decimal '\n' 0x0D hex
LF is Line Feed 10 decimal '\r' 0x0A hex
EDIT:
As you see below '\r' and '\n' are recognized characters. But when barcode printer reads [CR] I can't see it in my keyListener event. Can you comment here if something is still unclear ?
char LF='\r';
char CR='\n';
String whatINeed=CR+""+LF;
String whatIhave=""+CR;
String empty="";
for (char c : whatINeed.toCharArray()) {
System.out.println((int)c);
}
output
10
13
EDIT 2:
How it works on .Net Framework.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
char c = e.KeyChar;
textBox2.Text += $"{(int)c} | ({c}) {Environment.NewLine}";
if ((int)c == 13)
MessageBox.Show("Enter!!!");
}
Now I'll try to print a [CR] character only barcode and diagnose this more accurately.
Char 13=CR is handled as CTRL pressed + M in Java KeyListener event.
You can test this by pressing CTRL+M in notepad++.
This is the solution for handling just Carriage Return. Hope helps one else.
if(e.isControlDown()&&e.getKeyCode()==77)
ASCII Control Codes in Code 128 Barcodes
Home > Barcode Basics > Application Notes > AppNote022
Code 128 barcodes can include ASCII control codes as well as all the standard printable ASCII characters. A keyboard wedge scanner will read a barcode and transmit characters to the computer just as though they had been typed at the keyboard. The key codes transmitted from the keyboard and the wedge scanner are in a format particular to the PC architecture; they are not standard ASCII codes. Every standard ASCII character has an equivalent key code, and the keyboard wedge scanner automatically performs the conversion and sends the appropriate key code.
However, virtually all keyboards include many keys for which there are no ASCII equivalents: the F1 through F12 function keys, for example. These key codes can be sent from the keyboard to the computer, but there is no equivalent ASCII character that can be printed in a Code 128 barcode.
Many keyboard wedge scanners can be configured replace a specific barcode character with a different keyboard code. Since the keyboard wedge scanner transmits key codes to the computer, it can send any keyboard character. For example, a scanner could be configured to FS code (ASCII decimal 28) to an F10 key.
Here is a list of ASCII control codes. The first column lists the equivalent CTRL+key codes (^ used to indicate holding down the CTRL key):
Key ASCII
Function
^2 00 NUL null
^A 01 SOH start of header
^B 02 STX start transmission
^C 03 ETX end transmission
^D 04 EOT end of tape
^E 05 ENQ enquiry
^F 06 ACK acknowledge
^G 07 BEL bell
^H 08 BS backspace
^I 09 HT horizontal tab
^J 10 LF line feed
^K 11 VT vertical tab
^L 12 FF form feed
^M 13 CR carriage return
^N 14 SO shift out
^O 15 SI shift in
^P 16 DLE data link enable
^Q 17 DC1 device control 1
^R 18 DC2 device control 2
^S 19 DC3 device control 3
^T 20 DC4 device control 4
^U 21 NAK negative acknowledge
^V 22 SYN sync
^W 23 ETB
^X 24 CAN cancel
^Y 25 EM
^Z 26 SUB substitute
^[ 27 ESC escape
^\ 28 FS field separator
^] 29 GS group separator
^6 30 RS record separator
^- 31 US
After this comes the space bar (32) followed by the normal printable characters.
http://www.makebarcode.com/info/appnote/app_022.html
Here is the complete code, instead of KeyAdapter I used KeyListener implementation and wrote my code under KeyPressed not KeyRelased to handle Ctrl is down.
textFieldSquareBarcode.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==77&&e.isControlDown()) {
//DO_IT(); !!!
};
}}
);

System.in.read using my char value as an int? [duplicate]

What does :
System.in.read()
return ? The documentation says :
Returns:
the next byte of data, or -1 if the end of the stream is reached.
But for example if I enter : 10 I get back 49 . Why is that ?
49 is the ASCII value of the char 1. It is the value of the first byte.
The stream of bytes that is produced when you enter 10Enter on your console or terminal contains the three bytes {49,48,10} (on my Mac, may end with 10,12 or 12 instead of 10, depending on your System).
So the output of the simple snippet
int b = System.in.read();
while (b != -1) {
System.out.println(b);
b = System.in.read();
}
after entering a 10 and hitting enter, is (on my machine)
49
48
10
System.in.read() reads just one byte.
49 is the Unicode point value for 1.
Try to print:
System.out.println((char)49);
This will help you to understand it more.
When you enter 10, it is not read as an integer but as a String or, more precisely here, an array of bytes.
49 is the ASCII code for the character 1.

Using 'printf' in Java

I am having problems implementing the printf method into my code. I started my first Java course this week and am trying to get ahead of the class. Essentially, I am to create an output of ASCII characters, hexadecimal numbers, and their decimal equivalents, up to 127 entries. The number of rows created in the output is chosen by user input. This is the code I have so far:
package lab1;
import java.util.Scanner;
public class Lab1 {
public static void main(String[] args) {
//declare
Scanner scan = new Scanner(System.in);
//prompt the user to enter an integer, num defines the # of rows displayed in output
System.out.print("How many groups? ");
int num = scan.nextInt();
//print ascii, then hex value, then dec value
for (int c = 0; c < 128; c++) {
String hex = Integer.toString(c , 16);
String output = (char)c + " " + hex + " " + c;
System.out.println(output);
/*
//print the output with printf to create the columns
//character (c), string(s), decimal integer(d)
System.out.printf("%-2c %-2s %-2d", output);
*/
}
}
}
I would have posted an image here showing what the final result should look like but I need 10 reputation. I am able to email a copy to you privately though.
I hope you can help me understand how to accomplish this, or direct me to a resource where I am able to learn myself.
Thanks!
You need to pass the same number of arguments as you have flags in your printf.
for (int c = 0; c < 128; c++) {
// String hex = Integer.toString(c , 16); - No need for this anymore.
// Print the output with printf to create the columns
// character (c), string(s), decimal integer(d)
System.out.printf("%-2c 0x%-2X %-2d%n", (char)c, c, c);
}
With 0x%-2X, you can print out uppercase Hex values. I added 0x as a prefix to specify the base.
Example output:
...
A 0x41 65
B 0x42 66
C 0x43 67
D 0x44 68
E 0x45 69
F 0x46 70
G 0x47 71
H 0x48 72
I 0x49 73
J 0x4A 74
K 0x4B 75
L 0x4C 76
M 0x4D 77
N 0x4E 78
O 0x4F 79
P 0x50 80
Q 0x51 81
R 0x52 82
S 0x53 83
T 0x54 84
U 0x55 85
V 0x56 86
W 0x57 87
X 0x58 88
Y 0x59 89
Z 0x5A 90
...
You don't actually need to pass multiple arguments.
for (int c = 0; c < 128; c++) {
// Print ASCII, then hex, then dec
System.out.printf("%1$-2c %1$-2x %1$-2d%n", c);
}
See the docs here: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
The problem is you need three arguments for you printf, one each for char, String and decimal. Since you are passing only one variable (which is of type String) it gets confused. Remember, concatenating everything in one String(output) makes all a type String.
You need each tag to correspond with a variable, and your tags need to be formatted correctly.
To print an ascii, hex, and decimal value, your printf statement should look something like this:
System.out.printf("%-2c - %-2x - %-2f", someChar, someHex, someFloat);
where someChar is a char, someHex is an int whose hex value you wish to display, and someFloat is the float/double value you wish to display.
For more information on format strings in Java see: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

how to search for number digits and print the total in a text file for java?

I have a code that I need to find the most frequent digit number and print out the total number of the digits from the decimal numbers in my file. my code is:
65-43+21= 43
65.0-43.0+21.0= 43.0
65 -43 +21 = 43
65.0 -43.0 +21.0 = 43.0
65 - 43 + 21 = 43
65.00 - 43.0 + 21.000 = +0043.0000
65 - 43 + 21 = 43
the output should say:
Digit:
18 0
How would I go by doing this? should I use a Character.IsDigit() function, or make an array for it? Can somebody help me out with this? Thanks.
Read text file char by char. Use Guava HashMutilset to store digit chars. Iterate over HashMutilset.Entrys and determine the char with max occurences.

What does System.in.read actually return?

What does :
System.in.read()
return ? The documentation says :
Returns:
the next byte of data, or -1 if the end of the stream is reached.
But for example if I enter : 10 I get back 49 . Why is that ?
49 is the ASCII value of the char 1. It is the value of the first byte.
The stream of bytes that is produced when you enter 10Enter on your console or terminal contains the three bytes {49,48,10} (on my Mac, may end with 10,12 or 12 instead of 10, depending on your System).
So the output of the simple snippet
int b = System.in.read();
while (b != -1) {
System.out.println(b);
b = System.in.read();
}
after entering a 10 and hitting enter, is (on my machine)
49
48
10
System.in.read() reads just one byte.
49 is the Unicode point value for 1.
Try to print:
System.out.println((char)49);
This will help you to understand it more.
When you enter 10, it is not read as an integer but as a String or, more precisely here, an array of bytes.
49 is the ASCII code for the character 1.

Categories