Strange behavior while decoding hex characters to ASCII in Java - java

I wrote a Java program to take the lines of a file, and sort out a specific id which will then be converted to ASCII characters from HEX. Worked great for a couple of files until it found out the "0D" HEX character which seems to be carriage return (no idea what that does).
When it encounters that, it ends the line output (which it shouldn't do). I can't figure out what's happening.
This is the code, which compiles with no error. I've attached a picture with the result.
The file 1 contains the characters until the ID=xxx:LENGHT=8 and after that the 8 HEX characters needed to convert. after that, the program converts and add the text in the same line. I need them to be on the same line to figure out the pattern.
import java.io.*;
import java.util.Scanner;
import java.io.FileWriter;
import java.io.IOException;
public class FrameDecoder {
public static void main(String[] args) throws IOException {
try {
// Sortam frameurile cu id-ul tinta
File fisierSursa = new File("file1.txt"); //Fisierul original
FileWriter fisierData = new FileWriter("file2.txt"); //Fisierul cu frameurile care au id-ul cautat
FileWriter fisierTranzit = new FileWriter("file3.txt"); //Fisier cu caractere HEX, care va fi sters.
Scanner citireSursa = new Scanner(fisierSursa);
while (citireSursa.hasNextLine()){
String data = citireSursa.nextLine();
//System.out.println("data = " + data);
int intIndex = data.indexOf("ID=289"); // idul pe care il cauti
int intIndex2 = data.indexOf("ID=1313"); //al doilea id pe care il cauti
if (intIndex != -1 || intIndex2 != -1){
char[] text = data.toCharArray();
int counter = 0;
for (int i=0; i<text.length; i++){
if (text[i] == ':' && counter < 5){
counter++;
}
if (text[i] == ':' && counter == 5){
fisierTranzit.write(text[i+1]);
fisierTranzit.write(text[i+2]);
}
}
fisierTranzit.write("\r\n");
fisierData.write(data + "\r\n");
}
}
citireSursa.close();
fisierTranzit.close();
fisierData.close();
// Convertire HEX to ASCII
FileWriter fisierAscii = new FileWriter("file4.txt"); //Fisier care va contine caraterele ASCII decodate
File fisierTranzitRedeschis = new File("file3.txt"); //Reinitializam fisierul tranzit pentru a putea citi din el
Scanner citireTranzit = new Scanner(fisierTranzitRedeschis);
while (citireTranzit.hasNextLine()){
String data2 = citireTranzit.nextLine();
System.out.println("data2 = " + data2);
if (data2.length() % 2 != 0){
System.err.println("Invalid hex string!");
return;
}
StringBuilder builder = new StringBuilder();
for (int i=0; i<data2.length(); i=i+2){
//Impartim sirul in grupe de cate doua caractere
String s = data2.substring(i, i+2);
//Convertim fiecare grup in integer folosinf valueOfTheMetod
int n = Integer.valueOf(s, 16);
//Convertim valoare integer in char
builder.append((char)n);
}
fisierAscii.write(builder.toString() + "\r\n");
//System.out.println(builder.toString());
}
citireTranzit.close();
fisierAscii.close();
//Stergem fisierul 3
File stergereFisier3 = new File("file3.txt");
if(stergereFisier3.delete()){
System.out.println("File 3 deleted successfully");
}else{
System.out.println("Failed to delete file 3");
}
// Combinam fisierele
PrintWriter fisierFinal = new PrintWriter("file5.txt");
BufferedReader br1 = new BufferedReader(new FileReader("file2.txt"));
BufferedReader br2 = new BufferedReader(new FileReader("file4.txt"));
String line1 = br1.readLine();
String line2 = br2.readLine();
//loop to copy lines
//of file1.txt and file2.txt
//to file3.txt alternatively
while (line1 != null || line2 !=null){
if(line1 != null){
fisierFinal.print(line1 + " ");
line1 = br1.readLine();
}
if (line2 != null){
fisierFinal.println(line2 );
line2 = br2.readLine();
}
}
fisierFinal.flush();
//closing resources
br1.close();
br2.close();
fisierFinal.close();
System.out.println("Merged files succesfully");
//Stergem fisierul 2 si 4
File stergereFisier2 = new File("file2.txt");
File stergereFisier4 = new File("file4.txt");
if(stergereFisier2.delete() && stergereFisier4.delete()){
System.out.println("Files 2 and 4 deleted successfully");
}else{
System.out.println("Failed to delete files 2 and 4");
}
}catch (FileNotFoundException e){
System.out.println("An error occurred.");
e.printStackTrace();
}catch (IOException e){
System.out.println("No data to print");
e.printStackTrace();
}
}
}
Edit: I've cheated a little and place a condition when printing the HEX characters, if encounters 0D, just replacem them with 00. It worked. I'll also try your method, that one seems more ok than mine.
for (int i=0; i<text.length; i++){
if (text[i] == ':' && counter < 5){
counter++;
}
if (text[i] == ':' && counter == 5){
if(text[i+1] == '0' && text[i+2] == 'D'){
fisierTranzit.write('0');
fisierTranzit.write('0');
}
else{
fisierTranzit.write(text[i+1]);
fisierTranzit.write(text[i+2]);
}
}
}

The carriage return character \r (hex 0D) is one of the standard line separator characters, and Scanner.hasNextLine() and nextLine() methods assume it must terminate the current line.
To get more control, set the delimiter for Scanner to just the line feed character \n and use hasNext/next methods instead of hasNextLine/nextLine methods. For example:
Scanner citireTranzit = new Scanner(fisierTranzitRedeschis);
citireTranzit.useDelimiter("\n");
while (citireTranzit.hasNext()){
String data2 = citireTranzit.next();
...
}

Related

How can i use splitter ^ in java

I have a problem with my java program. I have to read lines from a file, the form of these lines is:
1#the^cat#the^dog#the^bird#^fish#bear
2#the^cat#the^dog#the^bird#^fish#bear
and print all, accept the "#" and "^" at textfields in my GUI. The "^" must appear in case there in not article. For exaple ^fish, i have to print it as ^fish but the^dog i have to print the dog.
As far i can read and print the lines in the textfields but i can't find a way to skip the "^" between the words.
Here is my code:
try {
FileReader file = new FileReader("C:\\Guide.txt");
BufferedReader BR = new BufferedReader(file);
boolean eof = false;
int i=0;
while (!eof) {
String line = BR.readLine();
if (line == null)
eof = true;
else {
i++;
System.out.println("Parsing line "+i+" <"+line+">");
String[] words = line.split("#");
if (words.length != 7) continue;
number=words[0];
onomastiki=words[1];
geniki=words[2];
aitiatiki=words[3];
klitiki=words[4];
genos=words[5];
Region=words[6];
E = new CityEntry(number,onomastiki,geniki,
aitiatiki,klitiki,
genos,Region);
Cities.add(E);
}
You can try something like this.
FileReader file = new FileReader("C:\\\\Users\\\\aq104e\\\\Desktop\\\\text");
BufferedReader BR = new BufferedReader(file);
boolean eof = false;
int i = 0;
while (!eof) {
String line = BR.readLine();
if (line == null)
eof = true;
else {
i++;
System.out.println("Parsing line " + i + " <" + line + ">");
String[] words = line.split("#");
for (int j = 0; j < words.length; j++) {
if(words[j].contains("^")) {
if(words[j].indexOf("^") == 0) {
// write your code here
//This is case for ^fish
}else {
// split using ^ and do further manipulations
}
}
}
}
}
Let me know if this works for you.
That is gonna work, but it is not best way)
foreach(String word : words){
if(word.contains"the"){
word.replace("^"," ");
}
}

Java Reading text from a file then coverting it to morse

Java 11.6
I am trying to write a java class that will take in a filename as a parameter then read line by line of that file. After it is done reading it will convert the file to equivalent morse code. My other methods such as "print morse table" "convert string to morse" works as it should but for the file function, every time I type the file name it just gives me an empty output. Not sure where exactly is the problem. I am posting the method underneath.
public void encodeFile(String s){
try{
BufferedReader br = new BufferedReader(new FileReader(s));
while((br.readLine()) != null){
String st="";
if( st ==" "||st==null){
System.out.println("");
}else{
int length = st.length();
for(int i=0;i<length;i++){
char c = st.charAt(i);
int x = c;
if(x>96 && x<123){
c = Character.toUpperCase(c);
}
if(c==' '){
System.out.printf(" ");
}else{
for(int j=0; j<listCodes.length; j++){
if(c==listCodes[j].getCharacter()){
System.out.printf(listCodes[j].getEncoding() + " ");
break;
}
if(listCodes[j+1]==null){
System.out.printf("?");
break;
}
}
}
}
}
System.out.printf("%n");
}
br.close();
}catch (Exception e){
System.out.println("java.lang.Exception: Invalid File Name: " + s);
}
}
The problem is that you are not storing the value of br.readLine() into st. Apart from this, you should use .equals instead of == to compare two strings.
Do it as follows:
public void encodeFile(String s){
try{
BufferedReader br = new BufferedReader(new FileReader(s));
String st="";
while((st = br.readLine()) != null){ // Store the value of `br.readLine()` into `st` and check if it is not null
if(st.equals(" ")){ // You need not check `st` for null again.
System.out.println("");
}else{
//...
}
//...

How to read a file from a specific line to another specific line?

So I'm trying to make a file reader to read from x line to y line but when i execute the program it reads all the lines of the file and not the lines that should have started and ended, For example if i'm looking an ID in the file it should print de ID, The name of the holder(the next line of the ID Line), and his/her address(Next line of the name Line), but instead of print just that it prints all the ID'S, Names and Addresses of everyone in the file.
System.out.println("Escriba el ID Del Cliente");
CL.setID(reader.next());
String line2;
int count = 0;
try {
BufferedReader input = new BufferedReader(new FileReader(file));
Scanner input2 = new Scanner(file);
PrintWriter output = new PrintWriter(new FileOutputStream(file, true));
LineNumberReader readers = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
while((line2 = input.readLine()) != null)
{
if(line2.contains(CL.getID()))
{
while(((line2 = readers.readLine()) != null) && readers.getLineNumber() <= count + 3)
{
count++;
System.out.println(line2);
}
input.close();
input2.close();
output.close();
readers.close();
break;
}
}
}catch(IOException ex)
{
System.out.println("ERRORR!!!!!!");
}
I've modified your code because the problem was at the count++ which will eventually led to reading all the lines from your files, and at the line2 = readers.readLine() which will read from the first line of the file again ( the program works half correct because it reads only 3 lines and only if line2 contains your ID ). Now, to make your program work correctly, you need to either use the BufferedReader or the LineNumberReader.
public static void main(String[] args) {
System.out.println("Escriba el ID Del Cliente");
String line2;
File file = new File(yourpathhere);
int lineCount = 0;
try {
PrintWriter output = new PrintWriter(new FileOutputStream(file, true));
LineNumberReader readers = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
while ((line2 = readers.readLine()) != null) {
lineCount++;
if (line2.contains(CL.getId())) {
while (line2 != null && readers.getLineNumber() <= lineCount + 3) {
System.out.println(line2);
line2 = readers.readLine();
}
output.close();
readers.close();
break;
}
}
} catch (IOException ex) {
System.out.println("ERRORR!!!!!!");
}
}
PS : pay attention for the getLineNumber() method because it increments the lines read until the moment you're calling it. It means that if we didn't had the lineCount and the ID we're trying to find was at the 6th line, the getLineNumber() value at the moment when line2.contains(CL.getId()) == true was 6, so the readers.getLineNumber() <= 3 will be FALSE and the program won't work correctly anymore. ( We need to keep track for the lines read until the moment we check for the id )
Assuming you have a file with 100 lines and you want to check and print out line 5 to 10 you could try this:
System.out.println("Escriba el ID Del Cliente");
CL.setID(reader.next());
String line;
int count = 0;
int xLine = 5;
int yLine = 10;
try (BufferedReader input = new BufferedReader(new FileReader(file)))
{
while((line = input.readLine()) != null)
{
if(count < xLine)
{
// skip all lines lower then start
continue;
}
else if(count >= xLine && count <= yLine && line.contains(CL.getID()))
{
// print line if line is between lines to read
// and if line contains ID
System.out.println(line);
}
else
{
// break if count is bigger then yLine
break;
}
count++;
}
}
catch(IOException ex)
{
System.out.println("ERRORR!!!!!!");
}
You read all lines till the BufferedReader reaches null. You check if the line contains your ID. Then you check if the count is between the linenumbers you want to check / print. Then you increment the count for the lines processed.
I simplified the try-catch-Block with a try-with-ressources Statement. As for now I don't see what your plans with output and scanner were, so I removed them.

Unexpected output filling an array with characters read from a text file

I'm trying to read a text file called input.in an array of characters representing a map. The file contains two integers N and numLifes, and the corresponding matrix. N represents the dimension of a square matrix (NxN).
I want that if N is less than 10, assign to the variable N, the value of 10 and fill the matrix 'mVill' with a '#', and then read the map file and integrate it with the matrix filled with '#'. Heres the code:
import java.io.*;
import java.io.FileReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class hola {
public static void main(String[] args) {
char mVill[][] = null;
int N, i,j, numLifes;
String line=null;
StringTokenizer tk;
char caract;
FileInputStream fstream = null;
try {
fstream = new FileInputStream("C:/input.in");
} catch (FileNotFoundException e) {
System.exit(-1);
}
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
try {
if ((line = br.readLine()) == null) {
System.out.print("Error empty file...");
System.exit(0);
}
} catch (IOException e) {
}
tk = new StringTokenizer(line);
N = Integer.parseInt(tk.nextToken());
numLifes = Integer.parseInt(tk.nextToken());
int nAux=N;
if (N<10){
N=10;
mVill = new char[N][N];
for (char[] row: mVill)
Arrays.fill(row, '#');
for (i=0; i <nAux; i++) {
for (j=0;j<nAux;j++){
try{
caract = (char) br.read();
mVill[i][j]=caract;
}catch (Exception e){
System.out.println("Error in read file");
}
}
}
}else{
mVill = new char[N][N];
for (i = 0; i < N; i++) {
try {
mVill[i] = br.readLine().toCharArray();
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
System.out.println(N+" "+numLifes);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
System.out.print(mVill[i][j]);
}
System.out.println();
}
}//end main
}//end class
For this input:
7 3
F..*..F
.##.##.
.#...#.
*..P..*
.#...#.
.##.##.
F..*..F
the output is (which is wrong):
F..*..F###
.##.####
#.
.#.###
..#.
*###
..P..*
###
.#...####
.
.##.###
##########
##########
##########
The output should I expect to receive it:
F..*..F###
.##.##.###
.#...#.###
*..P..*###
.#...#.###
.##.##.###
F..*..F###
##########
##########
##########
What am I doing wrong? I do not see any error in reading the file.
Following Steve's answer, the quick and dirty way to correct it would be to do this when you are reading your characters:
caract = (char) br.read();
while (caract == '\n' || caract == '\r') {
caract = (char) br.read();
}
mVill[i][j]=caract;
So the linefeed and carriage return characters would be skipped.
I think you're not taking the carriage-return / linefeed characters into account when reading the input. I would probably use a different technique, where you read a line at a time rather than a single character.
Try testing the character to see if it is a cr/lf and skip it if so.

java regular expression getting values from a txt file [duplicate]

I am new to Java. I have one text file with below content.
`trace` -
structure(
list(
"a" = structure(c(0.748701,0.243802,0.227221,0.752231,0.261118,0.263976,1.19737,0.22047,0.222584,0.835411)),
"b" = structure(c(1.4019,0.486955,-0.127144,0.642778,0.379787,-0.105249,1.0063,0.613083,-0.165703,0.695775))
)
)
Now what I want is, I need to get "a" and "b" as two different array list.
You need to read the file line by line. It is done with a BufferedReader like this :
try {
FileInputStream fstream = new FileInputStream("input.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int lineNumber = 0;
double [] a = null;
double [] b = null;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
lineNumber++;
if( lineNumber == 4 ){
a = getDoubleArray(strLine);
}else if( lineNumber == 5 ){
b = getDoubleArray(strLine);
}
}
// Close the input stream
in.close();
//print the contents of a
for(int i = 0; i < a.length; i++){
System.out.println("a["+i+"] = "+a[i]);
}
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
Assuming your "a" and"b" are on the fourth and fifth line of the file, you need to call a method when these lines are met that will return an array of double :
private static double[] getDoubleArray(String strLine) {
double[] a;
String[] split = strLine.split("[,)]"); //split the line at the ',' and ')' characters
a = new double[split.length-1];
for(int i = 0; i < a.length; i++){
a[i] = Double.parseDouble(split[i+1]); //get the double value of the String
}
return a;
}
Hope this helps. I would still highly recommend reading the Java I/O and String tutorials.
You can play with split. First find the line in the text that matches "a" (or "b"). Then do something like this:
Array[] first= line.split("("); //first[2] will contain the values
Then:
Array[] arrayList = first[2].split(",");
You will have the numbers in arrayList[]. Be carefull with the final brackets )), because they have a "," right after. But that is code depuration and it is your mission. I gave you the idea.

Categories

Resources