Java System.out.println only prints what's after VT character - java

I'm receiving data from a rabbit queue that I'm trying to convert to String. The message always starts with the SOH character and always ends with a VT character, followed by an ETX character. The data is received correctly and the byte array printed to the console is correct. The problem is that after converting to String, all the characters in the System.out.println before the VT and ETX are omitted. I first thought that the byte[] to String conversion might be done wrong by me, but I think there might be an issue with printing to the console that I'm missing.
Here's all the conversion approaches that I tried:
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
System.out.println("received message");
String message1 = new String(delivery.getBody(), StandardCharsets.US_ASCII);
String message2 = new String(delivery.getBody(), StandardCharsets.UTF_8);
String message3 = new String(delivery.getBody(), StandardCharsets.UTF_16);
String message4 = new String(delivery.getBody(), StandardCharsets.UTF_16BE);
String message5 = new String(delivery.getBody(), StandardCharsets.UTF_16LE);
String message6 = new String(delivery.getBody(), StandardCharsets.ISO_8859_1);
String message7 = new String(delivery.getBody());
String message8 = Base64.getEncoder().encodeToString(delivery.getBody());
String message9 = new String(Base64.getEncoder().encode(delivery.getBody()), StandardCharsets.UTF_8);
System.out.println(Arrays.toString(delivery.getBody()) + " - " + delivery.getBody().length);
System.out.println("1 " + message1 + " - " + message1.length() + " - ");
System.out.println("2 " + message2 + " - " + message2.length() + " - ");
System.out.println("3 " + message3 + " - " + message3.length() + " - ");
System.out.println("4 " + message4 + " - " + message4.length() + " - ");
System.out.println("5 " + message5 + " - " + message5.length() + " - ");
System.out.println("6 " + message6 + " - " + message6.length() + " - ");
System.out.println("7 " + message7 + " - " + message7.length() + " - ");
System.out.println("8 " + message8 + " - " + message8.length() + " - ");
System.out.println("9 " + message9 + " - " + message9.length() + " - ");
};
The System.out.println for messages 1, 2, 6, 7 print only VT, ETX and what is after, but nothing of what is before. The others are not properly converted and print asian characters or other random chars.

Special characters
These are control characters
SOH is start of header, ASCII code 1
VT is vertical tab, ASCII code 11, escaped "\v"
ETX is end of text, ASCII code 3, escaped "\0x3"
See also:
What is a vertical tab?
C0 and C1 control codes for message transmission
These control characters have not only special meaning (semantics) for printing but only for text transmission.
Maybe you need to put a special message-conversion component into place, when receiving data from a RabbitMQ text-message queue.

Related

Regex: Only returns message string - That's starts with messages and string between parent message curly brace

I want to get all the message data only. Such that it should look for message and all the data between curly braces of the parent message. With the below code, I am getting service details too along with message which I don't want. Any suggestion on this experts thanks in advance.
String data = "/**\r\n" +
" * file\r\n" +
" */\r\n" +
"syntax = \"proto3\";\r\n" +
"package demo;\r\n" +
"\r\n" +
"import \"envoyproxy/protoc-gen-validate/validate/validate.proto\";\r\n" +
"import \"google/api/annotations.proto\";\r\n" +
"import \"google/protobuf/wrappers.proto\";\r\n" +
"import \"protoc-gen-swagger/options/annotations.proto\";\r\n" +
"\r\n" +
"option go_package = \"bitbucket.com;\r\n" +
"option java_multiple_files = true;\r\n" +
"\r\n" +
"schemes: HTTPS;\r\n" +
"consumes: \"application/json\";\r\n" +
"produces: \"application/json\";\r\n" +
"responses: {\r\n" +
"key:\r\n" +
" \"404\";\r\n" +
"value: {\r\n" +
"description:\r\n" +
" \"not exist.\";\r\n" +
"schema: {\r\n" +
"json_schema: {\r\n" +
"type:\r\n" +
" STRING;\r\n" +
"}\r\n" +
"}\r\n" +
"}\r\n" +
"}\r\n" +
"responses: {\r\n" +
"key:\r\n" +
" \"401\";\r\n" +
"value: {\r\n" +
"description:\r\n" +
" \"Wrong user.\";\r\n" +
"schema: {\r\n" +
"json_schema: {\r\n" +
"type:\r\n" +
" STRING;\r\n" +
"};\r\n" +
"example: {\r\n" +
"value:\r\n" +
" '{ \"message\": \"wrong user.\" }'\r\n" +
"}\r\n" +
"}\r\n" +
"}\r\n" +
"}\r\n" +
"\r\n" +
"message message1 {\r\n" +
" message message2 {\r\n" +
" enum Enum {\r\n" +
" UNKNOWN = 0; \r\n" +
" }\r\n" +
" }\r\n" +
" string id = 1;\r\n" +
" string name = 3;\r\n" +
" string account = 4;\r\n" +
"}\r\n" +
"\r\n" +
"message User{\r\n" +
" string firstName = 1 ;\r\n" +
" string lastName = 2 ;\r\n" +
" string middleName = 3 [(validate.rules).repeated = { min_items: 0 }];\r\n" +
"}\r\n" +
"\r\n" +
"service Userlogin{\r\n" +
" rpc Login(User) returns (APIResponse);\r\n" +
"}";
List<String> allmsg = Arrays.asList(data.replaceAll("(?sm)\\A.*?(?=message)", "").split("\\R+(?=message)"));
I am expecting response like below in my array list of string with size 2.
allMsg.get(0) should be
message message1 {
message message2 {
enum Enum {
UNKNOWN = 0;
}
}
string id = 1;
string name = 3;
string account = 4;
}
allMsg.get(1) should be
message User{
string firstName = 1 ;
string lastName = 2 ;
string middleName = 3 [(validate.rules).repeated = { min_items: 0 }];
}
Use a Pattern that matches a "message" and stream the match results to a List:
List<String> allmsg = Pattern.compile("(?ms)^message.*?^}")
.matcher(data)
.results() // stream the MatchResults
.map(MatchResult::group) // get the entire match
.collect(toList()); // collect as a List
See live code demo.
Regex breakdown:
(?ms) turns on flags s, which makes dot also match newlines, and m, which makes ^ and $ match start and end of each line
^message matches start of a line (not start of input, thanks to the m flag) then "message"
.*? reluctantly (ie as little as possible) matches any characters (including newlines, thanks to the s flag). Adding the ? to make the quantifier reluctant stops the match from consuming multiple "messages".
^} matches start of a line (not start of input, thanks to the m flag) then "}"
See live regex demo.
This will work even if "messages" are not contiguous with each other, ie they may be interspersed with other constructs (your example doesn't have this situation, but the linked demos do).
You should see you other question.
Pattern.compile("(?s)^message(.(?!message|service))*");
If message can appear after message
"message message1 {\r\n" +
You must adapt the regex.

Java error handling for project- Line matched except underscores: Invalid Event Code_?

I completed this java project for a class, but I cannot seem to fix the error I'm getting for the web software that grades it- it's called webcat. I've tried the test input the software suggests for a reference test against my solution, and my output looks exactly the same, but I still lost points for this error-
"Error in method main of class Event: Line number 2 of your output is incorrect (line numbers begin at 1). Your main method does not print the correct output when the input is "This is a short test " (input less than 26 characters) [] Line matched except underscores: Invalid Event Code_".
How can I fix this error when the expected ouput looks fine? Thanks in advance!
Code:
public class Event {
/**
* accepts coded event info, prints the info back to std output, and
actual cost and prize number.
*
* #param args Command line arguments - not used.
*/
public static void main(String[] args) {
// variables needed
String shrink, event, date, time, section, row, seat;
double price, discount, cost;
int prizeNum;
// accept input
Scanner userInput = new Scanner(System.in);
// format the numbers
DecimalFormat formatNum = new DecimalFormat("$#,##0.00");
// enter input and trim the space
System.out.print("Enter your event code: ");
shrink = userInput.nextLine().trim();
if (shrink.length() < 26) {
System.out.println();
System.out.println("Invalid Event Code");
System.out.println("Event code must have at least 26 characters.");
return;
}
// locates spot in index of code and assigns
event = shrink.substring(25, shrink.length());
date = shrink.substring(0, 8);
time = shrink.substring(8, 12);
section = shrink.substring(19, 21);
row = shrink.substring(21, 23);
seat = shrink.substring(23, 25);
price = Double.parseDouble(shrink.substring(12, 15)
+ "." + shrink.substring(15, 17));
discount = Double.parseDouble(shrink.substring(17, 19));
// calculates final cost
cost = price - (price * (discount / 100));
// random final number
prizeNum = (int) (Math.random() * 1000 + 1);
// prints the data to std output
System.out.println();
System.out.print("Event: " + event + " " + " " + " ");
System.out.print("Date: " + date.substring(0, 2) + "/"
+ date.substring(2, 4) + "/" + date.substring(4, 8) + " "
+ " " + " ");
System.out.println("Time: " + time.substring(0, 2) + ":"
+ time.substring(2, 4) + " " + " " + " ");
System.out.print("Section: " + section + " " + " " + " ");
System.out.print("Row: " + row + " " + " " + " ");
System.out.println("Seat: " + seat);
System.out.print("Price: " + formatNum.format(price) + " " + " " + " ");
// formats discount before print
formatNum.applyPattern("#.#'%'");
System.out.print("Discount: " + formatNum.format(discount) + " "
+ " " + " ");
// formats cost before print
formatNum.applyPattern("$#,##0.00");
System.out.println("Cost: " + formatNum.format(cost));
System.out.print("Prize Number: " + prizeNum);
Output:
Enter your event code: This is a short test
Invalid Event Code
Event code must have at least 26 characters.

Can someone look at my code and tell me whats wrong?

So my requirement is to display a message showing yours and your friend's initials in lower case (ie. "mf and js are friends").
Here's my code
String myFullName = "Daniel Camarena";
String friendsFullName = "John Smith";
System.out.println( myFullName.toLowerCase().charAt(0)
+ myFullName.toLowerCase().charAt(7)
+ " and "
+ friendsFullName.toLowerCase().charAt(0)
+ friendsFullName.toLowerCase().charAt(5)
+ " are friends." );
The output I get is
199 and js are friends.
myFullName.toLowerCase().charAt(0) + myFullName.toLowerCase().charAt(7)
are working on ascii integer value and hence 199
The reason strings addition works for the second name is because that is part of the string formed due to this:
+ " and "
Quick fix, add an empty string at start
System.out.println("" + myFullName.toLowerCase().charAt(0)
+ myFullName.toLowerCase().charAt(7)
+ " and "
+ friendsFullName.toLowerCase().charAt(0)
+ friendsFullName.toLowerCase().charAt(5)
+ " are friends." );
System.out.println( "" + myFullName.toLowerCase().charAt(0) + myFullName.toLowerCase().charAt(7)
+ " and "
+ friendsFullName.toLowerCase().charAt(0)
+ friendsFullName.toLowerCase().charAt(5)
+ " are friends." );
Append the blank string to convert it to String and then it will start doing concanetation . As '+' is overloaded operator it is doing addition till it encounters String.
You can use following code :
String myFullName = "Daniel Camarena";
String friendsFullName = "John Smith";
String[] arrMyFullName = myFullName.toLowerCase().split(" ");
String[] arrFriendsFullName = friendsFullName.toLowerCase().split(" ");
String message = "";
for(String s : arrMyFullName)
message += s.charAt(0);
message += " and ";
for(String s : arrFriendsFullName)
message += s.charAt(0);
message += " are friends.";
System.out.println( message );
Above code also work if name is more than 2 words.
Try:
System.out.println( "" + myFullName.toLowerCase().charAt(0)
+ myFullName.toLowerCase().charAt(7)
+ " and "
+ friendsFullName.toLowerCase().charAt(0)
+ friendsFullName.toLowerCase().charAt(5)
+ " are friends." );
With this one you can have any name of friends. Instead of correcting the index which differs for each name.
String myFullName = "Daniel Camarena";
String friendsFullName = "John Smith";
String[] myNameSplit = myFullName.split(" ");
String myFirstInitial = String.valueOf(myNameSplit[0].charAt(0));
String myLastInitial = String.valueOf(myNameSplit[1].charAt(0));
String[] myFriendNameSplit = friendsFullName.split(" ");
String myFriendFirstInitial = String.valueOf(myFriendNameSplit[0].charAt(0));
String myFriendLastInitial = String.valueOf(myFriendNameSplit[1].charAt(0));
System.out.println(myFirstInitial+myLastInitial + " and " + myFriendFirstInitial+myFriendLastInitial+ " are friends");
It is adding ASCII value of d and c in output to avoid that do as following.
String myFullName = "Daniel Camarena";
String friendsFullName = "John Smith";
System.out.println( myFullName.toLowerCase().charAt(0)
+""+ myFullName.toLowerCase().charAt(7)
+ " and "
+ friendsFullName.toLowerCase().charAt(0)
+ friendsFullName.toLowerCase().charAt(5)
+ " are friends." );

How to split a NAME and ADDRESS, and print them separately

I'm starting with this String:
"NAME-RAHUL KUMAR CHOUDHARY ADDRESS-RAJDHANWAR DISTRICT-GIRIDIH STATE-JHARKHAND PIN CODE-825412"
I want to split the name and address, and print it like this:
NAME:RAHUL KUMAR CHOUDHARY , DDRESS-RAJDHANWAR DISTRICT-GIRIDIH STATE-JHARKHAND PIN CODE-825412. like this
This is what I have so far:
String str_colArow3 = colArow3.getContents();
//Display the cell contents
System.out.println("Contents of cell Col A Row 3: \""+str_colArow3 + "\"");
if(str_colArow3.contains("NAME"))
{
}
else if(str_colArow3.contains("ADDRESS"))
{
}
String string = "NAME-RAHUL KUMAR CHOUDHARY ADDRESS-RAJDHANWAR DISTRICT-GIRIDIH STATE-JHARKHAND PIN CODE-825412";
String[] parts = string.split("-");
string = "Name: " + parts[1].substring(0, parts[1].length() - 7)
+ "\nAdress: " + parts[2] + " - " + parts[3]
+ "\nPin Code: " + parts[5];
Something like this. Check out the split() method for strings, your string is a bit poorly formatted to use this, though. You have to adjust for your own needs.
Edit: Better way to do this, with different string input.
String string = "RAHUL KUMAR CHOUDHARY:RAJDHANWAR:GIRIDIH:JHARKHAND:825412";
String[] parts = string.split(":");
string = "Name: " + parts[0] + "\n"
+ "Address: " + parts[1] + "\n"
+ "District: " + parts[2] + "\n"
+ "State: " + parts[3] + "\n"
+ "Pin Code: " + parts[4] + "\n";

Why is the char value transforming during the output?

I am making my program to throw a die (as in dices) for a school assignment in Java SE. The user can place a character as standard input, so the character the user picks will represent the eyes of the die. Sometimes when I print the result, it shows a completely different character.
package ThrowADie;
import java.util.Scanner;
public class ThrowADie {
public static void main(String[] args) {
//Ask user for the char in which the dices eyes should be printed in.
System.out.print("Which character should I use for the eye: ");
//Allow user to place input in the eye variable
Scanner input = new Scanner(System.in); //Make the stdinput object
char eye = input.next().charAt(0);
//Time to throw the die. Place result in dieResult
int dieResult = throwDie();
//Reveal of the result
printDieResult(dieResult, eye);
}
/*
* Method name: throwDie()
* Purpose: Picks a number from 1 to 6 randomly, like a die does
* Parameters: N/A
* Returns: Integer number from 1 to 6
*/
public static int throwDie(){
int range = (6 - 1) + 1;
return (int)(Math.random() * range) + 1;
}
/*
* Method name: printDieResult()
* Purpose: Generate result of the die throw in ASCII art
* Parameters: numberOfEyes, typeOfEyes
* Returns: N/A
*/
public static void printDieResult(int numberOfEyes, char typeOfEyes){
if (numberOfEyes == 1){
//Print art
System.out.println(
" " + " " + " \n"
+ " " + typeOfEyes + " \n"
+ " " + " " + " ");
} else if (numberOfEyes == 2){
//Print art
System.out.println(
typeOfEyes + " " + " \n"
+ " " + " " + " \n"
+ " " + " " + typeOfEyes);
} else if (numberOfEyes == 3){
//Print art
System.out.println(
typeOfEyes + " " + " \n"
+ " " + typeOfEyes + " \n"
+ " " + " " + typeOfEyes);
} else if (numberOfEyes == 4){
//Print art
System.out.println(
typeOfEyes + " " + typeOfEyes + "\n"
+ " " + " " + " \n"
+ typeOfEyes + " " + typeOfEyes);
} else if (numberOfEyes == 5){
//Print art
System.out.println(
typeOfEyes + " " + typeOfEyes + "\n"
+ " " + typeOfEyes + " \n"
+ typeOfEyes + " " + typeOfEyes);
} else {
//Print art
//Accidentally written down 9 eye representation
System.out.println(
typeOfEyes + typeOfEyes + typeOfEyes + "\n"
+ typeOfEyes + typeOfEyes + typeOfEyes + "\n"
+ typeOfEyes + typeOfEyes + typeOfEyes);
}
}
}
Output
This program will generate proper results. But occasionally the char that has been input, that represent the eye of the die, transforms in to a number.
In the case below, the program should print 9 '#' characters. Instead it prints 192 on the first row. (I know dices have 6 eyes but I bumped into this strange output while accidentally printing 9 eyes)
run:
Which character should I use for the eyes: #
192
###
###
I can not find the cause of this, can anyone see what I have done wrong here?
Character arithmetic!
Consult this table. # is character 64
typeOfEyes + typeOfEyes + typeOfEyes + "\n"
This first line is actually adding up the values of the characters (64 + 64 + 64) = 192, then addending that with a newline, so we get 192\n.
The compiler is choosing to add those up rather than create a String of characters. The easy way to solve this is to preface that with an empty string in front: "" + typeOfEyes...
Basically, the compiler is "dumb." When we add integers to Strings, "foo" + 123 the compiler can interpret that as foo123 just fine because it recognizes the first element as a String. However, we've defined a char which is a numeric type representing a character. So the compiler does math with it. Even though we shouldn't be. Adding the String literal tells it we actually want text.
int test = (int) (typeOfEyes + typeOfEyes + typeOfEyes);
System.out.println("\n" + test + "\n"
+ typeOfEyes + "" + typeOfEyes + "" + typeOfEyes + "\n"
+ typeOfEyes + "" + typeOfEyes + "" + typeOfEyes + "\n"
+ typeOfEyes + "" + typeOfEyes + "" + typeOfEyes);
Which character should I use for the eye: #
192
###
###
###

Categories

Resources