How can I ignore comments statements /*.....*/ when i reading java file? - java

How can i ignore the comment statements that begin with "/*" and ends with
"*/" for example: /*the problem is..*/ or
/* problem is very difficult */ ,,i want to remove these statement when i reading java file line by line
public class filename1 {
public static void main (String args[])
{
try {
fileName = "C:\\NetBeansProjects\\filename\\src\\filename\\filename.java";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
line = br.readLine();
while (line !=null) {
for( int i=0;i<line.length();i++)
{
b=line.indexOf("/",i);
ee=line.indexOf("*",i);
if(b!=-1 && ee!=-1)
v=line.indexOf("*/",i);
if (v==-1)
line=" ";
}
System.out.println(line);
line = br.readLine();
}}
catch (IOException e)
{
e.printStackTrace();
}
}
}

Simply include:
int index = str.indexOf("/*");
while(index != -1) {
str = str.substring(0, index) + str.substring(str.indexOf("*/")+2);
index = str.indexOf("/*");
}
Edit:
Assuming that you have to account for fragments where you have a comment interrupted by the start or end of the string:
Edit2:
Now.. Also assuming that you have to take into account for literal string "/*" or "*/"
str = str.replace("\"/*\"", "literal_string_open_comment");
str = str.replace("\"*/\"", "literal_string_close_comment");
int start = str.indexOf("/*"), end = str.indexOf("*/");
while(start > -1 || end > -1) {
if(start != -1) {
if(end != -1) {
if(end < start) {
str = str.substring(end+2);
} else {
str = str.substring(0, start) + str.substring(end+2);
}
} else {
str = str.substring(0, start);
}
} else {
str = str.substring(end+2);
}
start = str.indexOf("/*");
end = str.indexOf("*/");
}
str = str.replace("literal_string_open_comment", "\"/*\"");
str = str.replace("literal_string_close_comment", "\"*/\"");

Related

Making changes to every line in a file - Java

I am working on a program that reads 5 different files containing code that is improperly indented. I have to write a method that properly indents the code and prints it to the console and a new file, given a tab size and the names of the input and output files as parameters. My code so far runs through and indents every line and then tries to determine when to indent another tab or unindent.
public static void justifyJava( String inputFileName, String outputFileName,
int tabSize ) throws FileNotFoundException {
String one_tab = "";
for (int i = 0; i < tabSize; i++) {
one_tab += " ";
}
Scanner input = new Scanner( new File (inputFileName));
PrintStream out = new PrintStream ( new File (outputFileName));
int lineCount = 0;
while ( input.hasNextLine() ) {
String line = input.nextLine();
line = one_tab + line.trim();
lineCount++;
if (lineCount == 1){
line = line.substring(tabSize);
}
else if (lineCount == 2){
Scanner lineScan = new Scanner(line);
while (lineScan.hasNext()) {
String token = lineScan.next();
if (token.length() <= 2) {
line = line.substring(tabSize);
}
}
}
else if (line.contains("{") && lineCount > 2){
System.out.println(line);
out.println(line);
line = one_tab + input.nextLine();
while(!(line.contains("}"))){
line = one_tab + line;
System.out.println(line);
out.println(line);
line = input.nextLine();
}
line = one_tab + line;
}
else if (line.contains("}") && input.hasNextLine()){
line = one_tab + line;
}
else if (!(input.hasNextLine())) {
line = line.substring(tabSize);
}
System.out.println(line);
out.println(line);
}
}
This way is becoming very tedious because of how many situations i have to account for especially since the code in these files use different curly brace styles. Essentially all I'm trying to do is indent every line that follows an opening curly brace by one tab and unindent every line that follows a closing curly brace by one tab. Is there an easier way to do this?
Determining "how many times" you have to indent a line is the same as knowing how many blocks of code opened before this line. To this end, you detect a new block of code if:
The string contains an opening bracket {.
The string contains a control statement, e.g. if.
The second approach is harder, since you have to determine if the string is actually a control statement and not part of a variable name.
Hence, a simple program, that does not cover every possible coding standard, but will work pretty decently works like this:
Search for an opening bracket that does not belong to a comment.
When you find it, recursively call the method passing the new indentation size.
Return after finding the end of the code block.
Here goes a MWE that works for most simple cases. It is able to detect opening and closing brackets outside strings, and does not search inside comment lines.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;
public class JavaIndent {
public static void main(String[] args) {
try {
JavaIndent.justify("path/to/input.java", "path/to/output.java", 4);
} catch (FileNotFoundException ex) {
System.out.println("File not found...");
}
}
public static void justify(String inputFileName, String outputFileName,
int tabSize) throws FileNotFoundException {
String one_tab = "";
for (int i = 0; i < tabSize; i++) {
one_tab += " ";
}
Scanner input = new Scanner(new File(inputFileName));
PrintStream out = new PrintStream(new File(outputFileName));
JavaIndent.justifyRecursion(one_tab, "", input, out);
}
private static String justifyRecursion(String base_tab, String tab, Scanner input, PrintStream out) {
String line;
boolean flag_open, flag_close, flag_comment, flag_empty;
while (input.hasNextLine()) {
line = input.nextLine().trim();
flag_open = JavaIndent.contains(line, "{");
flag_close = JavaIndent.contains(line, "}");
flag_empty = line.length() == 0;
flag_comment = (flag_empty) ? false : line.charAt(0) == '/';
if (flag_comment || flag_empty) {
out.println(tab + line);
} else if (flag_close) {
return line;
} else if (flag_open) {
out.println(tab + line + "ENTERED OPEN");
line = JavaIndent.justifyRecursion(base_tab, tab + base_tab, input, out);
out.println(tab + line);
// Handles statements like } else { and sequences of these.
flag_open = JavaIndent.contains(line, "{");
while (flag_open) {
line = JavaIndent.justifyRecursion(base_tab, tab + base_tab, input, out);
out.println(tab + line);
flag_open = JavaIndent.contains(line, "{");
}
} else {
// Just a regular line, nothing special
out.println(tab + line);
}
}
return "";
}
private static boolean contains(String line, String sequence) {
String current = "";
char ch, last_ch = ' ';
int count_quotation = 0;
ArrayList<String> code_without_strings = new ArrayList<>();
for (int k = 0; k < line.length(); ++k) {
ch = line.charAt(k);
if (ch == '"' && count_quotation == 0 && last_ch != '\'') {
code_without_strings.add(current);
current = "";
++count_quotation;
} else if (ch == '"' && count_quotation == 1) {
if (last_ch != '\\') {
count_quotation = 0;
}
}
if (count_quotation == 0) {
current += ch;
}
last_ch = ch;
}
code_without_strings.add(current);
for (String code : code_without_strings) {
if (code.contains(sequence))
return true;
}
return false;
}
}
However, one still needs to consider statements such as this:
if (condition)
System.out.println("This should be indented, but it won't be...");
and this:
/**
* This is just a comment, but the program will indent from here on {.
*/
Try using JavaIndent to indent JavaIndent.java and verify that at the very end you will get
if (code.contains(sequence))
return true;
instead of
if (code.contains(sequence))
return true;

How do I stop the program from replicating a line that has /r/n in front of it?

Parts works apart from when I read in /r/n in front of some characters it does what I want then replicates the line and keeps /r/n.
I have written a program and I want it to scan through a file and replace special characters with values I want.
Please is there something I am missing?
Have a look look at the code below.
public synchronized String theMessage() {
int type;
String rmCarReturn;
String newLine;
String val;
String str = "", fin = "";
String par;
int index = -1;
Scanner sc = new Scanner(message);
while (sc.hasNextLine()) {
str = sc.nextLine();
if (str.isEmpty())
;
else if (str.charAt(0) == '<') {
par = str.substring(1, str.indexOf('>'));
if ((index = param.indexOf(par + "//" + messages)) != -1) {
par += "//" + messages;
} else
index = param.indexOf(par);
if (index < 0) {
logger.info("Param " + par + "not found");
sc.close();
throw new paramNotFoundException(par + "not found");
} else {
type = param.getType(par);
val = param.getValue(par);
if (type == 0)
fin += val;
if (type == 1) {
fin += loadData(par);
}
if (type == 2) {
fin += calculateCorrelation(par);
}
if (type == 3) {
fin += loadFunctons(par);
}
}
}
if (str.charAt(0) == '/')
fin += str.substring(1);
//Carriage return
if(str.substring(0, Math.min(str.length(),4)).equals("\\r\\n")){
rmCarReturn = str.substring(4);
newLine = (String.format("%n") + rmCarReturn );
fin += newLine;
}
if((str.substring(str.length() - 4).equals("\\r\\n"))){
rmCarReturn = str.substring(0, str.length()-4);
newLine = rmCarReturn + String.format("%n");
fin += newLine;
}
//End of Carriage return
else {
fin += str;
}
}
sc.close();
data.nextIteration();
return fin;
}
Simplest way to think of is keep the original line (you've already red) in a variable, then extract the content you need via replacing the new line /r/n. Once you've processed what you need just continue to iterate the file reading it line by line. Something like this:
try( BufferedReader reader = new BufferedReader( ... ) ) {
reader.lines().foreach( line -> processLine( line ) );
}
in your processLine(String line) pass and extract the content of the line using String's replaceAll("(\\\\r)?\\\\n", "").

When reading file with Java Scanner, it hangs after the last line has been processed

My method is able to read all the lines of the file but then it gets stuck at the last line and never reaches scanner.close() and onwards. I'm not sure why? I invoke scanner.nextLine() so surely it should detect this and scanner.hasNextLine() should return false when the file ends. Is there a quick fix that I have overlooked here?
private int[] GetNumberOfRowsAndColumns(BufferedReader br) {
Scanner scanner = new Scanner(br);
String line = "";
int column_max = 0;
int total_rows = 0;
int[] result = new int[1];
try {
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.length() > column_max) {
column_max = line.length();
}
total_rows++;
}
} catch (Exception e) {
System.err.println(e);
}
scanner.close();
result[0] = column_max;
result[1] = total_rows;
return result;
}
The file in question:
+++++++++++++++++
+0A +
+AA ++++
+ +
+ ++A+
+ +a+
+++++++++++++++++
EDIT:
public SearchClient(BufferedReader serverMessages) throws Exception {
Map<Character, String> colors = new HashMap<Character, String>();
String line, color;
int agentCol = -1, agentRow = -1;
int colorLines = 0, levelLines = 0;
// Read lines specifying colors
while ((line = serverMessages.readLine())
.matches("^[a-z]+:\\s*[0-9A-Z](,\\s*[0-9A-Z])*\\s*$")) {
line = line.replaceAll("\\s", "");
String[] colonSplit = line.split(":");
color = colonSplit[0].trim();
for (String id : colonSplit[1].split(",")) {
colors.put(id.trim().charAt(0), color);
}
colorLines++;
}
if (colorLines > 0) {
error("Box colors not supported");
}
int[] result = getNumberOfRowsAndColumns(serverMessages);
System.err.println("MAX COLUMNS = " + result[0]);
System.err.println("MAX ROWS = " + result[1]);
initialState = new Node(null);
while (!line.equals("")) {
for (int i = 0; i < line.length(); i++) {
char chr = line.charAt(i);
if ('+' == chr) { // Walls
initialState.walls[levelLines][i] = true;
} else if ('0' <= chr && chr <= '9') { // Agents
if (agentCol != -1 || agentRow != -1) {
error("Not a single agent level");
}
initialState.agentRow = levelLines;
initialState.agentCol = i;
} else if ('A' <= chr && chr <= 'Z') { // Boxes
initialState.boxes[levelLines][i] = chr;
} else if ('a' <= chr && chr <= 'z') { // Goal cells
initialState.goals[levelLines][i] = chr;
}
}
line = serverMessages.readLine();
levelLines++;
}
}
By convention, Java methods start with a lower case letter. Next, your array can only hold one value (length of 1) and you don't need a Scanner (use your BufferedReader). Finally, you can make an anonymous array. Something like,
private int[] getNumberOfRowsAndColumns(BufferedReader br) {
int column_max = 0;
int total_rows = 0;
try {
String line;
while ((line = br.readLine()) != null) {
// if (line.length() > column_max) {
// column_max = line.length();
// }
column_max = Math.max(column_max, line.length());
total_rows++;
}
} catch (Exception e) {
System.err.println(e);
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return new int[] { column_max, total_rows };
}

java.util.NoSuchElementException: No line found*

I keep getting this error
java.util.NoSuchElementException No line found
when I use this method
public boolean hasMoreCommands() {
if (input.hasNextLine()) {
return true;
} else {
//input.close();
return false;
}
}
public void advance() {
String str;
if(hasMoreCommands() == true){
do {
str = input.nextLine().trim();
// Strip out any comments
if (str.contains("//")) {
str = (str.substring(0, str.indexOf("//"))).trim();
}
} while (str.startsWith("//") || str.isEmpty() || hasMoreCommands());
command = str;
}
}
I have main code here:
public class Ptest
{
public Ptest(String fileName)
{
String line = null;
String nName = fileName.replace(".vm", ".asm");
Parser p = new Parser();
try{
File neF = new File(nName);
if(!neF.exists()){
neF.createNewFile();
}
File tempFile = new File("temp.txt");
if(!tempFile.exists()){
tempFile.createNewFile();
}
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(nName);
BufferedWriter bw = new BufferedWriter(fw);
FileWriter writR = new FileWriter(tempFile);
BufferedWriter buffR = new BufferedWriter(writR);
while((line = br.readLine()) != null) {
buffR.write(line+ "\n");
//System.out.println(line);
}
buffR.flush();
buffR.close();
p.insertTitle(tempFile);
String ctype = p.commandType();
int len = ctype.length();
int spaces = 13 - len;
String sp = " ";
String asp = " ";
String a1 = null;
int a2;
int alen;
boolean t = false;
while(p.hasMoreCommands()){
for(int i= 0; i < spaces; i++){
sp += " ";
}
t = p.hasMoreCommands();
a1 = p.arg1();
alen = (10 - a1.length());
for(int i= 0; i < alen; i++){
asp += " ";
}
//a2 = p.arg2();
if (ctype == "C_PUSH" || ctype == "C_POP" || ctype == "C_FUNCTION" || ctype == "C_CALL") {
a2 = p.arg2();
bw.write(ctype + sp + a1 + asp + a2);
}
else {
bw.write(ctype + sp + a1);
}
p.advance();
ctype = p.commandType();
len = ctype.length();
spaces = 13 - len;
}
bw.flush();
bw.close();
}
catch(FileNotFoundException ex){
System.out.println("File not found!");
}
catch(IOException ex){
System.out.println("Error reading file '" + fileName + "'");
}
}
}
I went through debugger and it literally goes the entire file then gives me an error when its finished.
Like #hfontanez I think your problem is in this code:
if(hasMoreCommands() == true){
do {
str = input.nextLine().trim();
// Strip out any comments
if (str.contains("//")) {
str = (str.substring(0, str.indexOf("//"))).trim();
}
} while (str.startsWith("//") || str.isEmpty() || hasMoreCommands());
command = str;
}
However, my solution is to change the while clause to while (str.isEmpty() && hasMoreCommands());
I'm assuming that "advance" ought to return the next non-comment / blank line.
If the string from the previous pass is empty (after stripping any comment) it will go round the loop again provided that wasn't the last line. But, if that was the last line or str still has something in it, then it will exit the loop. Comments should have been stripped so don't need tested for in the while.
I think if you just test for hasNextLine within the loop then it will never exit the loop if the last line was comment / blank.
My guess is that your problem is here:
if(hasMoreCommands() == true){
do {
str = input.nextLine().trim();
// Strip out any comments
if (str.contains("//")) {
str = (str.substring(0, str.indexOf("//"))).trim();
}
} while (str.startsWith("//") || str.isEmpty() || hasMoreCommands());
command = str;
}
The exception you encountered (NoSuchElementException) typically occurs when someone tries to iterate though something (String tokens, a map, etc) without checking first if there are any more elements to get. The first time the code above is executed, it checks to see if it has more commands, THEN it gets in a loop. The first time it should work fine, however, if the test done by the while() succeeds, the next iteration will blow up when it tries to do input.nextLine(). You have to check is there is a next line to be got before calling this method. Surround this line with an if(input.hasNextLine()) and I think you should be fine.

How to replace a String at a specific index in a text file in Java

My text file contains:
Hello This is a Test
Press Enter to Continue
I have an array of:
int StartIndex [] = {1,4,8}
int EndIndex [] = {3,7,11}
String[] VALUES = new String[] {"Sys","Jav","Tes"};
I want to replace index{1,3} with 'Sys', index{4,7} with 'Jav' and so on in the file.
My idea is to read the whole file as a String and then pass on the indexes to replace with the VALUES Strings.
How can I do this ?
CODE:
String[] VALUES = new String[] {"Sys"}; //Correct Solutions
int [] StartIndex ={4};
int [] EndIndex ={6};
while ((line = br.readLine()) != null) {
// Print the content on the console
System.out.println (line);
StringBuffer buf = new StringBuffer(line);
buf.replace(StartIndex[0], EndIndex[0], VALUES[0]);
done =buf.toString();
System.out.println(done);
Expected Ouput should be like this:
SyslJavhTes is a Test
Press Enter to Continue
I searched a bit and got this:
String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);
If we convert the file to string and apply this function ,will this work?
Problem Solved! Code works perfectly because I tested it. Like before no comments have been added so you will understand & learn. (Please vote/accept answer if it works for others to identify the correct answer).
CODE:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
*
* #author jtech
*/
public class ReplaceWithIndexes
{
public static void main(String[] args) throws IOException
{
BufferedReader br = null;
boolean endMatched = false;
int startIndex[] = {0,4,8};
int endIndex[] = {3,7,10};
int c = 0, c1 = 0, c2 = 0, largestVal_start = 0, largestVal_end = 0, lineCount = 0;
String line = null, newString = "";
String[] VALUES = new String[] {"Sys","Jav","Tes"};
br = new BufferedReader(new FileReader("C:\\Users\\jtech\\Documents\\NetBeansProjects\\HelpOthers\\src\\textFiles\\AnotherFile.txt"));
for (int i = 0; i < startIndex.length; i++)
{
if (startIndex[i] > largestVal_start)
{
largestVal_start = startIndex[i];
}
}
for (int i = 0; i < endIndex.length; i++)
{
if (endIndex[i] > largestVal_end)
{
largestVal_end = endIndex[i];
}
}
while ((line = br.readLine()) != null)
{
StringBuilder buf = new StringBuilder(line);
// Print the content on the console
System.out.println(line);
lineCount++;
while (c <= largestVal_start)
{
while (c1 <= largestVal_end)
{
if (startIndex[0] == c && endIndex[0] == c1)
{
buf.replace(startIndex[0], endIndex[0], VALUES[c2]);
newString = buf.toString();
endMatched = true;
}
else if (startIndex[1] == c && endIndex[1] == c1)
{
buf.replace(startIndex[1], endIndex[1], VALUES[c2]);
newString = buf.toString();
endMatched = true;
}
else if (startIndex[2] == c && endIndex[2] == c1)
{
buf.replace(startIndex[2], endIndex[2], VALUES[c2]);
newString = buf.toString();
endMatched = true;
}
c1++;
}
for (int i = 0; i < startIndex.length; i++)
{
if (c == startIndex[i])
{
c2++;
}
}
if (endMatched == true || ((c1 <= largestVal_end) == false) )
{
c1 = 0;
endMatched = false;
}
c++;
}
if (lineCount <= 1)
{
System.out.println("Updated line: " + newString);
}
}
}
}
In Java, the class is the proverbial hammer and every problem really is a nail. You need one for your case, too, instead of managing three separate arrays.
class Replacer {
private final int start, end;
private final String replacement;
Replacer(int start, int end, String replacement) {
this.start = start; this.end = end; this.replacement = replacement;
}
String replace(String in) {
StringBuilder b = new StringBuilder(in);
b.replace(start, end, replacement);
return b.toString();
}
}
Then create a list of replacers:
List<Replacer> replacers = Arrays.asList(
new Replacer(1, 3, "System"),
new Replacer(4, 7, "Java"),
new Replacer(8, 11, "Testing")
);
and apply them on each line:
while ((line = br.readLine()) != null) {
for (Replacer r : replacers) line = r.replace(line);
System.out.println(line);
}
The simplest solution would be the following code, but it's probably not efficient enough for huge files and/or large numbers of replaces.
while ((line = br.readLine()) != null) {
// Print the content on the console
System.out.println (line);
StringBuffer buf = new StringBuffer(line);
for (int i = 0; i < VALUES.length; i ++) {
buf = buf.replace(StartIndex[i], EndIndex[i], VALUES[i]);
}
done = buf.toString();
System.out.println(done);
}

Categories