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.
Related
I know there are many similar questions here, but I still can't solve it. I can get all the results that I want. However, in the end, it still shows nullpointerexception. I don't know why. can anyone help?
public class PointGenterate {
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
try{
File file = new File("123.txt");
double[] pointsid = new double[10];
String[] data = null;
for(int i = 0; i <10; i++){
double rn = (int)(Math.random()*120);
System.out.println(rn);
pointsid[i] = rn;
}
//read file
InputStreamReader rs = new InputStreamReader(new FileInputStream(file));//create input stream reader object
BufferedReader br = new BufferedReader(rs);
String line = "";
line = br.readLine();
//
File write = new File("output.KML");
write.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(write));
while(line != null){
line = br.readLine();
if(line==" "){
System.out.print("empty");
}else{
data = line.split(",|:|[|]");
}
for(int i = 0; i < data.length; i++){
data[i] = data[i].trim();
System.out.println(data[i] + "num" + i);
}
if(data.length > 15){
double id = Double.parseDouble(data[4]);
for(int i = 0; i <10; i++){
if(id == pointsid[i]){
data[10] = data[10].substring(0, data[10].length()-2);
data[15] = data[15].substring(1,data[15].length());
data[16] = data[16].substring(0, data[16].length()-6);
out.write(data[8]+" "+ data[10]+ " " + data[13] + data[15] + data[16]+ "\r\n");
out.flush();
}
}
}
//System.out.println(line);
}
out.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
the txt file format is like
{ "type": "Feature", "properties": { "id": 126.000000, "osm_id": 4851918786.000000, "name": "Moray House Library", "type": "library" }, "geometry": { "type": "Point", "coordinates": [ -3.180841771200988, 55.950622362732418 ] } },
this is one line. I have many lines, and actually this is just a test code. if it works. i want to write it as a method in a javaseverlet class. get the string coordinates and return it to my JS font-end.
There's a few issues with your code. In this section:
InputStreamReader rs = new InputStreamReader(new FileInputStream(file));//create input stream reader object
BufferedReader br = new BufferedReader(rs);
String line = "";
line = br.readLine(); // here you read the first line in the file
//
File write = new File("output.KML");
write.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(write));
while(line != null){ // here you check that it's not null (it's not, you read the first line OK)
line = br.readLine(); // here you read the second line (there is no second line, now line is null)
if(line==" "){ // now you check if the line is a space character (this is wrong for 2 reasons, that's not how you compare strings, and a space character is not an empty string)
System.out.print("empty");
}else{
data = line.split(",|:|[|]"); // here you call split() on line but line is null
}
When you checked if the string was empty, you did line == " " which is wrong for 2 reasons. First you cannot use == to compare strings - read this question for details on why not. Second, " " is a string that contains a space character. "" is an empty string.
When you want to check if a string is empty you can do it like this:
line.equals("")
or like this:
line.isEmpty()
Here's your code with a few small changes so that it runs without throwing an exception.
public class PointGenterate {
public static void main(String[] args) throws Exception {
try {
File file = new File("123.txt");
double[] pointsid = new double[10];
String[] data = null;
for(int i = 0; i < 10; i++){
double rn = (int)(Math.random()*120);
System.out.println(rn);
pointsid[i] = rn;
}
//read file
InputStreamReader rs = new InputStreamReader(new FileInputStream(file));//create input stream reader object
BufferedReader br = new BufferedReader(rs);
String line = "";
//
File write = new File("output.KML");
write.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(write));
while((line = br.readLine()) != null){ // read the line and check for null
if(line.isEmpty()) { // is the line equal to the empty string?
System.out.print("empty");
} else {
data = line.split(",|:|[|]");
}
for(int i = 0; i < data.length; i++){
data[i] = data[i].trim();
System.out.println(data[i] + "num" + i);
}
if(data.length > 15){
double id = Double.parseDouble(data[4]);
for(int i = 0; i <10; i++){
if(id == pointsid[i]){
data[10] = data[10].substring(0, data[10].length()-2);
data[15] = data[15].substring(1,data[15].length());
data[16] = data[16].substring(0, data[16].length()-6);
out.write(data[8]+" "+ data[10]+ " " + data[13] + data[15] + data[16]+ "\r\n");
out.flush();
}
}
}
//System.out.println(line);
}
out.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
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 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", "\"*/\"");
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", "").
So, I'm working on a procedure that has an entry of a txt file called orders that specifies the number of words to bold and wich words must be bolded. I've managed to to it for one word but when i try with two words the output gets doubled. For example:
Input:
2
Ophelia
him
Output:
ACT I
ACT I
SCENE I. Elsinore. A platform before the castle.
SCENE I. Elsinore. A platform before the castle.
FRANCISCO at his post. Enter to him BERNARDO
FRANCISCO at his post. Enter to *him* BERNARDO
Here's my code, can anyone help me? PS: Ignore the boolean I guess.
static void bold(char bold, BufferedReader orders, BufferedReader in, BufferedWriter out) throws IOException
{
String linha = in.readLine();
boolean encontrou = false;
String[] palavras = new String[Integer.parseInt(orders.readLine())];
for (int i = 0; i < palavras.length; i++)
{
palavras[i] = orders.readLine();
}
while (linha != null)
{
StringBuilder str = new StringBuilder(linha);
for (int i = 0; i < palavras.length && !encontrou; i++)
{
if (linha.toLowerCase().indexOf(palavras[i]) != -1)
{
str.insert((linha.toLowerCase().indexOf(palavras[i])), bold);
str.insert((linha.toLowerCase().indexOf(palavras[i])) + palavras[i].length() + 1, bold);
out.write(str.toString());
out.newLine();
}
else
{
out.write(linha);
out.newLine();
}
}
linha = in.readLine();
}
}
This merits a regular expression replace of WORD-BOUNDARY + ALTERNATIVES + WORD-BOUNDARY.
String linha = in.readLine(); // Read number of words to be bolded.
String[] palavras = new String[Integer.parseInt(orders.readLine())];
for(int i = 0; i < palavras.length; i++){
palavras[i]=orders.readLine();
}
// We make a regular expression Pattern.
// Like "\\b(him|her|it)\\b" where \\b is a word-boundary.
// This prevents mangling "shimmer".
StringBuilder regex = new StringBuilder("\\b(");
for (int i = 0; i < palavras.length; i++) {
if (i != 0) {
regex.append('|');
}
regex.append(Pattern.quote(palavras[i]));
}
regex.append(")\\b");
Pattern pattern = Pattern.compile(regex.toString(), Pattern.CASE_INSENSITIVE);
boolean encontrou = false;
linha = in.readLine(); // Read first line.
while(linha != null){
Matcher m = pattern.matcher(linha);
String linha2 = m.replaceAll(pattern, "*$1*");
if (linha2 != linha) {
encontrou = true; // Found a replacement.
}
out.write(linha2);
out.newLine();
linha = in.readLine(); // Read next line.
}
A replaceAll (instead of replaceFirst) then replaces all occurrences.
It's writing out twice because you output your StringBuilder (out.write(str.toString())) for the line (linha) every time you iterate through it, which will be at least the number of words in the lookup list.
Move the out.write() statements outside the loop and you should be fine.
Note this will only find one match in each line for each word. If you need to find more than one, the code is a little more complicated. You need to introduce a while loop instead of your if test for matching, or you could consider using replaceAll() using a regular expression based on your word palavras[i]. Ensuring you respected the capitalisation of the original is not simple there, but possible.
Fixed version
static void bold(char bold, BufferedReader orders, BufferedReader in, BufferedWriter out)
throws IOException
{
String linha = in.readLine();
boolean encontrou = false;
String[] palavras = new String[Integer.parseInt(orders.readLine())];
for (int i = 0; i < palavras.length; i++)
{
palavras[i] = orders.readLine();
}
while (linha != null)
{
StringBuilder str = new StringBuilder(linha);
for (int i = 0; i < palavras.length && !encontrou; i++)
{
if (linha.toLowerCase().indexOf(palavras[i]) != -1)
{
str.insert((linha.toLowerCase().indexOf(palavras[i])), bold);
str.insert(
(linha.toLowerCase().indexOf(palavras[i])) + palavras[i].length() + 1,
bold);
}
}
out.write(str.toString());
out.newLine();
linha = in.readLine();
}
}
With replaceAll
static void bold(char bold, BufferedReader orders, BufferedReader in, BufferedWriter out)
throws IOException
{
String linha = in.readLine();
boolean encontrou = false;
String[] palavras = new String[Integer.parseInt(orders.readLine())];
for (int i = 0; i < palavras.length; i++)
{
palavras[i] = orders.readLine();
}
while (linha != null)
{
for (int i = 0; i < palavras.length && !encontrou; i++)
{
String regEx = "\\b("+palavras[i]+")\\b";
linha = linha.replaceAll(regEx, bold + "$1"+bold);
}
out.write(linha);
our.newLine();
linha = in.readLine();
}
}
P.S. I've left the found boolean (encontrou) in, although it is not doing anything at the moment.