When I use FileInputStream to input text from my spawn.txt file for a tile-based map, it adds extra whitespace in-between each line.
package mapInit;
import java.io.FileInputStream;
public class SpawnMap {
static char[][] spawnWorld = new char[30][30];
public static void main(String[] args) {
try {
FileInputStream spawn = new FileInputStream("Resources/Map/spawn.txt");
int i = 0;
int h = 0;
int k = 0;
while((i=spawn.read())!=-1){
if(h == 30) {
h = 0;
k++;
}
spawnWorld[k][h] = (char)i;
h++;
}
spawn.close();
} catch (Exception e) {
}
for (int i=0; i<30; i++) {
for (int j=0;j<30;j++) {
System.out.println(spawnWorld[i][j]);
}
}
}
}
This is the result of the output loop:
This is a picture of the text file:
GitHub Link: https://github.com/WeaponGod243/Machlandia
I think Scanner class it's more suitable for your task
Scanner class in Java is found in the java.util package. Java provides
various ways to read input from the keyboard, the java.util.Scanner
class is one of them.
The Java Scanner class breaks the input into tokens using a delimiter
which is whitespace by default. It provides many methods to read and
parse various primitive values.
The Java Scanner class is widely used to parse text for strings and
primitive types using a regular expression. It is the simplest way to
get input in Java. By the help of Scanner in Java, we can get input
from the user in primitive types such as int, long, double, byte,
float, short, etc.
The Java Scanner class extends Object class and implements Iterator
and Closeable interfaces.
The Java Scanner class provides nextXXX() methods to return the type
of value such as nextInt(), nextByte(), nextShort(), next(),
nextLine(), nextDouble(), nextFloat(), nextBoolean(), etc. To get a
single character from the scanner, you can call next().charAt(0)
method which returns a single character.
Source
Scanner Java Doc
public static void main(String arg[]) {
try (Scanner sc = new Scanner(new File("Resources/Map/spawn.txt"))) {
// Checking if sc has another token in the file
while(sc.hasNext()) {
// Print line
System.out.println(sc.next());
}
} catch (Exception ex) {
// Use a Logger to log exceptions in real projects
ex.printStackTrace();
}
}
You could use Apache Commons IO library too
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class ReadTextFile {
public static void main(String[] args) throws IOException {
try {
File f = new File("Resources/Map/spawn.txt");
List<String> lines = FileUtils.readLines(f, "UTF-8");
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
// Use a Logger to log exceptions in real projects
e.printStackTrace();
}
}
}
Change the System.out.println inside your loop to just System.out.print.
System.out.println will automatically add a newline character every time, even if you're only printing a single character. System.out.print will take the String you pass in, and print it as is.
Here's a link to the official Javadoc:
https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#print-java.lang.String-
Also, unless it's on purpose, verify you're not printing the \n (newline character) at the end of each line. If you actually want to start a new line at the end of each line, simply put a System.out.println(); line after the end of the innermost loop.
I have looked at your codes. It seems by using this I have detected that by using FileInputStream it will produce an empty space in between the values.
static char[][] spawnWorld = new char[30][30];
public static void main(String[] args) {
try {
FileInputStream spawn = new FileInputStream("C:/Daniel/spawn.txt");
int i = 0;
int h = 0;
int k = 0;
while ((i = spawn.read()) != -1) {
if (h == 30) {
h = 0;
k++;
}
spawnWorld[k][h] = (char) i;
if (h == 19) System.out.println((char) i);
System.out.println("[" + k + "][" + h + "] : " + i);
h++;
}
spawn.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Start Printing");
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
System.out.println("[" + i + "][" + j + "] : " + spawnWorld[i][j]);
}
}
System.exit(0);
}
From then on you may debug it accordingly.
At line 19, your 'i' returns a blank space or char value i.
I would suggest to use the Scanner as your way to read the file instead.
A text file is made up of characters on a line followed by end-of-line sequences, typically newlines or carriage returns followed by newlines. (These can also be thought of as line separators rather than line endings, and the last line might not be followed by one, depending on how the file was created.) You are reading the file character by character but you make no allowance for these end of line characters.
It doesn't make any difference whether you use FileInputStream or Scanner; the problem is, you read the file one character at a time but don't account for carriage return and newline.
For example:
while ((i=spawn.read()) != -1) {
if (Character.isWhitespace((char)i)) {
continue;
}
if (h == 30) {
h = 0;
k++;
}
spawnWorld[k][h] = (char)i;
h++;
}
Related
The main thing I am trying to do is input a .txt file into a 2d char array. The problem is that no data is being saved into the array, so I'm thinking my problem lies with the fact that there is no in-between string from the .txt file to the array. I tried using file and buffered readers so I would have a string, and it works, but it adds null many many times. Can someone point out what I am doing wrong here? (I am very new to java, sorry for any errors in question format and such)
See code below, where I'm encountering the problem.
Scanner scanner = new Scanner(new File("Code.txt"));
try {
//had a problem trying to just get the chars out from a file just as a string
// so to a filereader we go!
FileReader Enigma = new FileReader("Code.txt");
// when looking at filereaders, i found bufferedreaders
// they seem to help with reading chars better than the filereader alone
BufferedReader CryptoMachine = new BufferedReader(Enigma);
for (i = 0; i <= rows-1; i++)
{
for (j = 0; j <= columns-1; j++)
{
sentence = CryptoMachine.readLine();
System.out.print(sentence);
}
}
CryptoMachine.close();
}
catch (FileNotFoundException e) {
System.out.println("No file found");
}
Return I get:
This is ridiculously hardnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
Whole code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
// TODO block code
public class Enigma {
// TODO block code
public static void main(String[] args) throws IOException {
// double array set up here
String sentence = "";
int rows = 6;
int columns = 7;
char[][] RotaryMachine = new char[rows][columns];
boolean flag = false;
// told this lets me declare variables on the same line
int i = 0,j = 0;
// scanner to scan a file here
Scanner scanner = new Scanner(new File("Code.txt"));
try {
//had a problem trying to just get the chars out from a file just as a string
// so to a filereader we go!
FileReader Enigma = new FileReader("Code.txt");
// when looking at filereaders, i found bufferedreaders
// they seem to help with reading chars better than the filereader alone
BufferedReader CryptoMachine = new BufferedReader(Enigma);
for (i = 0; i <= rows-1; i++)
{
for (j = 0; j <= columns-1; j++)
{
sentence = CryptoMachine.readLine();
System.out.print(sentence);
}
}
CryptoMachine.close();
}
catch (FileNotFoundException e) {
System.out.println("No file found");
}
for(i = 0; j > columns && !flag;++i)
{
if(i < rows && !scanner.hasNext())
{
System.out.println("The English have our codes");
flag = true;
}
RotaryMachine[i][j] = scanner.next().charAt(0);
if(i > 6)
{
j++;
}
RotaryMachine[i][j] = '*';
}
// RotaryMachine[0][0] = 'a';
//now, to hopefully code the scrambler section properly, for Enigma to work!
// V2 seems to keep letters really close together
for(i=0;i < columns;++i)
{
for(j = 0;j < rows;++j)
{
System.out.printf("%c", RotaryMachine[j][i]);
}
}
// V1 of the code seems to space out the letters
// for(j=0;j < rows;++j)
// {
// for(i = 0;i < columns;++i)
// {
// System.out.printf("%c", RotaryMachine[j][i]);
// }
// }
}
}
Since the file being read only has one line, readLine will return null for every call past the first since there are no more lines to read.
You can String.split the initial string after reading it if you so desire.
I am looking for an amount of substring in a file
In brief, the file contains a certain amount of article, and I need to know how many.
Each article starts with: #ARTICLE{
or with #ARTICLE{(series of integer)
Useful infos:
- I have 10 files to look in
- No files are empty
- This code gives me a StringIndexOutOfBounds exception
Here is the code I have so far:
//To read through all files
for(int i=1; i<=10; i++)
{
try
{
//To look through all the bib files
reader = new Scanner(new FileInputStream("C:/Assg_3-Needed-Files/Latex"+i+".bib"));
System.out.println("Reading Latex"+i+".bib->");
//To read through the whole file
while(reader.hasNextLine())
{
String line = reader.nextLine();
String articles = line.substring(1, 7);
if(line.equals("ARTICLE"))
count+=1;
}
}
catch(FileNotFoundException e)
{
System.err.println("Error opening the file Latex"+i+".bib");
}
}
System.out.print("\n"+count);
Try just using String#contains on each line:
while(reader.hasNextLine()) {
String line = reader.nextLine();
if (line.contains("ARTICLE")) {
count += 1;
}
}
This would at least get around the problem of having to take a substring in the first place. The problem is that while matching lines should not have the out of bounds exception, nor should lines longer than 7 characters which don't match, lines having fewer than 7 characters would cause a problem.
You could also use a regex pattern to make sure that you match ARTICLE as a standalone word:
while(reader.hasNextLine()) {
String line = reader.nextLine();
if (line.matches("\\bARTICLE\\b")) {
count += 1;
}
}
This would ensure that you don't count a line having something like articles in it, which is not your exact target.
You can check if line starts with needed sequence:
if (line.startsWith("ARTICLE")) {
count += 1;
}
You're getting an StringIndexOutOfBounds from this line of code:
String articles = line.substring(1, 7);
The line read in can be empty or have less than 7 characters. To avoid getting the StringIndexOutOfBounds you should have a conditional check to see if the
line.length > 7
Aside from that then its better to use the answers recommended above (ie .contains or .startsWith)
Since you are reading line by line so, string.contains is good choice instead of substring, on the other hand all article start with "#ARTICLE", Therefore use "#ARTICLE" in condition. For code test, please try this -
public class test {
public static void main(String[] args) {
int count = 0;
for (int i = 1; i <= 10; i++) {
try {
//To look through all the bib files
Scanner reader = new Scanner(new FileInputStream("C:/Assg_3-Needed-Files/Latex" + i + ".bib"));
System.out.println("Reading Latex" + i + ".bib->");
//To read through the whole file
while (reader.hasNextLine()) {
String line = reader.nextLine();
if (line.contains("#ARTICLE")) {
count += 1;
}
}
} catch (FileNotFoundException e) {
System.err.println("Error opening the file Latex" + i + ".bib");
}
}
System.out.print("\n" + count);
} }
When I try to compile a java file, the compiler said "illegal character \u3000",
after searching, I find it is CJK Unified Ideographs
Chinese Korean and Japanese's SPACE. Instead of deleting the special SPACE manually, I decide to code a simple search-and-deleting java file to eliminate it.
However It doesnot point out the index error.
So how to write a code to eliminate this special SPACE
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class BufferReadAFile {
public static void main(String[] args) {
//BufferedReader br = null;
String sCurrentLine;
String message = "";
try {
/*br = new BufferedReader(new FileReader("/Users/apple/Test/Instance1.java"));
while ((sCurrentLine = br.readLine()) != null) {
message += sCurrentLine;
}
*/
String content = new Scanner(new File("/Users/apple/Coding/Instance1.java")).useDelimiter("\\Z").next();
//System.out.println(content);
searchSubString(content.toCharArray(),"\\u3000".toCharArray());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void searchSubString(char[] text, char[] ptrn) {
int i = 0, j = 0;
// pattern and text lengths
int ptrnLen = ptrn.length;
int txtLen = text.length;
// initialize new array and preprocess the pattern
int[] b = preProcessPattern(ptrn);
while (i < txtLen) {
while (j >= 0 && text[i] != ptrn[j]) {
j = b[j];
}
i++;
j++;
// a match is found
if (j == ptrnLen) {
System.out.println("found substring at index:" + (i - ptrnLen));
j = b[j];
}
}
}
public static int[] preProcessPattern(char[] ptrn) {
int i = 0, j = -1;
int ptrnLen = ptrn.length;
int[] b = new int[ptrnLen + 1];
b[i] = j;
while (i < ptrnLen) {
while (j >= 0 && ptrn[i] != ptrn[j]) {
// if there is mismatch consider the next widest border
// The borders to be examined are obtained in decreasing order from
// the values b[i], b[b[i]] etc.
j = b[j];
}
i++;
j++;
b[i] = j;
}
return b;
}
}
I don't think "\\u3000" is what you want. You can print out the string and see the content yourself. You should use "\u3000" instead. Note the single back slash.
System.out.println("\\u3000"); // This prints out \u3000
System.out.println("\u3000"); // This prints out the CJK space
Alternatively, you could just use the actual CJK space character directly as in one of the if checks in your CheckEmpty class.
In my Question, I am trying to use KMP alogrithm to search the index of a pattern in my java file
if we use "\\u3000".toCharArray() the compiler will look through each character. Which is not what we want. \\u3000 is an special white space. It is FULL-WIDTH space that only existed in Chinese Korean and Japanese languages.
If we trying to write sentence by using the FULL-WIDTH Space. It will look like:
Here is Full-width demonstration.
Very distinctive space. but is not so visible in java file. It inspire me to write the code below
import java.util.*;
import java.io.*;
public class CheckEmpty{
public static void main(String []args){
try{
String content = new Scanner(new File("/Users/apple/Coding/Instance1.java")).useDelimiter("\\Z").next();
if(content.contains(" ")){
System.out.println("English Space");
}
if(content.contains("\\u3000")){
System.out.println("Backslash 3000");
}
if(content.contains(" ")){// notice the space is a SPECIAL SPACE
System.out.println("C J K fullwidth");
//Chinese Japanese Korean white space
}
}catch(FileNotFoundException e){
e.printStackTrace();
}
}
}
As expected, the result shows:
which means the java file contains both the normal and full-width Space.
After that I am thinking to write another java file to delete all the special space:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.*;
public class DeleteTheSpecialSpace {
public static void main(String[] args) {
//BufferedReader br = null;
String sCurrentLine;
String message = "";
try {
String content = new Scanner(new File("/Users/apple/Coding/Instance1.java")).useDelimiter("\\Z").next();
content.replaceAll(" ",""); // notice the left parameter is a SPECIAL SPACE
//System.out.println(content);
PrintWriter out = new PrintWriter( "/Users/apple/Coding/Instance1.java" );
out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Finally: amazing things happen, There is no error in "Instance1.java", since all full-width space have been eliminated
Compile SUCCESS :)
I'm writing a simple program to reformat source code using new line style curly brace to end of line curly brace style. I'm having trouble manipulating strings to then pass them to an arraylist.
My specific problem is when I find a line which has a new line curly brace, I then get the index of the line before, set the new line to the element in the previous index and append a "{", I am having trouble removing the previous line.
I've tried doing .remove(previousIndex) but it did not work
Sample input:
public class Reformat
{
public static void main(String[] args)
{
System.out.println("Test 1");
System.out.println("Test 2");
}
}
This is my code so far:
public class Reform {
public static void main(String[] arg) throws FileNotFoundException {
// Pass source file to File object
File sourceFile = new File(arg[0]);
// Create AL of type String to hold tokens
ArrayList<String> code = new ArrayList<String>();
Scanner input = null;
// Try-catch block to handle any errors while opening the file
try {
input = new Scanner(sourceFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
while (input.hasNextLine()) {
String currentLine = input.nextLine();
if (currentLine.isEmpty()) {
continue;
} else if (currentLine.contains("{") && code.size() != 0) {
int previousIndex = code.size() - 1;
code.add(code.set(previousIndex, code.get(previousIndex) + "{"));
} else {
code.add(currentLine);
}
}//end of while
for (String line : code)
System.out.println(line);
}//end of finally
input.close();
}//end of main
}//end of class
I played around with the code in question and was able to resolve by arranging in this manner:
else if (currentLine.contains("{") && code.size() != 0) {
int previousIndex = code.size() - 1;
String newLine = code.set(previousIndex, code.get(previousIndex) + "{");
code.add(previousIndex, newLine);
code.remove(previousIndex);
Not 100% sure why it worked in this way and not the other attempts. I would appreciate an explanation. The worst type of solutions are the ones you don't understand.
This is wrong:
code.add(code.set(previousIndex, code.get(previousIndex) + "{"));
It should be:
code.set(previousIndex, code.get(previousIndex) + "{");
I'm having a problem counting the number of words in a file. The approach that I am taking is when I see a space or a newLine then I know to count a word.
The problem is that if I have multiple lines between paragraphs then I ended up counting them as words also. If you look at the readFile() method you can see what I am doing.
Could you help me out and guide me in the right direction on how to fix this?
Example input file (including a blank line):
word word word
word word
word word word
You can use a Scanner with a FileInputStream instead of BufferedReader with a FileReader. For example:-
File file = new File("sample.txt");
try(Scanner sc = new Scanner(new FileInputStream(file))){
int count=0;
while(sc.hasNext()){
sc.next();
count++;
}
System.out.println("Number of words: " + count);
}
I would change your approach a bit. First, I would use a BufferedReader to read the file file in line-by-line using readLine(). Then split each line on whitespace using String.split("\\s") and use the size of the resulting array to see how many words are on that line. To get the number of characters you could either look at the size of each line or of each split word (depending of if you want to count whitespace as characters).
This is just a thought. There is one very easy way to do it. If you just need number of words and not actual words then just use Apache WordUtils
import org.apache.commons.lang.WordUtils;
public class CountWord {
public static void main(String[] args) {
String str = "Just keep a boolean flag around that lets you know if the previous character was whitespace or not pseudocode follows";
String initials = WordUtils.initials(str);
System.out.println(initials);
//so number of words in your file will be
System.out.println(initials.length());
}
}
Just keep a boolean flag around that lets you know if the previous character was whitespace or not (pseudocode follows):
boolean prevWhitespace = false;
int wordCount = 0;
while (char ch = getNextChar(input)) {
if (isWhitespace(ch)) {
if (!prevWhitespace) {
prevWhitespace = true;
wordCount++;
}
} else {
prevWhitespace = false;
}
}
I think a correct approach would be by means of Regex:
String fileContent = <text from file>;
String[] words = Pattern.compile("\\s+").split(fileContent);
System.out.println("File has " + words.length + " words");
Hope it helps. The "\s+" meaning is in Pattern javadoc
import java.io.BufferedReader;
import java.io.FileReader;
public class CountWords {
public static void main (String args[]) throws Exception {
System.out.println ("Counting Words");
FileReader fr = new FileReader ("c:\\Customer1.txt");
BufferedReader br = new BufferedReader (fr);
String line = br.readLin ();
int count = 0;
while (line != null) {
String []parts = line.split(" ");
for( String w : parts)
{
count++;
}
line = br.readLine();
}
System.out.println(count);
}
}
Hack solution
You can read the text file into a String var. Then split the String into an array using a single whitespace as the delimiter StringVar.Split(" ").
The Array count would equal the number of "Words" in the file.
Of course this wouldnt give you a count of line numbers.
3 steps: Consume all the white spaces, check if is a line, consume all the nonwhitespace.3
while(true){
c = inFile.read();
// consume whitespaces
while(isspace(c)){ inFile.read() }
if (c == '\n'){ numberLines++; continue; }
while (!isspace(c)){
numberChars++;
c = inFile.read();
}
numberWords++;
}
File Word-Count
If in between words having some symbols then you can split and count the number of Words.
Scanner sc = new Scanner(new FileInputStream(new File("Input.txt")));
int count = 0;
while (sc.hasNext()) {
String[] s = sc.next().split("d*[.#:=#-]");
for (int i = 0; i < s.length; i++) {
if (!s[i].isEmpty()){
System.out.println(s[i]);
count++;
}
}
}
System.out.println("Word-Count : "+count);
Take a look at my solution here, it should work. The idea is to remove all the unwanted symbols from the words, then separate those words and store them in some other variable, i was using ArrayList. By adjusting the "excludedSymbols" variable you can add more symbols which you would like to be excluded from the words.
public static void countWords () {
String textFileLocation ="c:\\yourFileLocation";
String readWords ="";
ArrayList<String> extractOnlyWordsFromTextFile = new ArrayList<>();
// excludedSymbols can be extended to whatever you want to exclude from the file
String[] excludedSymbols = {" ", "," , "." , "/" , ":" , ";" , "<" , ">", "\n"};
String readByteCharByChar = "";
boolean testIfWord = false;
try {
InputStream inputStream = new FileInputStream(textFileLocation);
byte byte1 = (byte) inputStream.read();
while (byte1 != -1) {
readByteCharByChar +=String.valueOf((char)byte1);
for(int i=0;i<excludedSymbols.length;i++) {
if(readByteCharByChar.equals(excludedSymbols[i])) {
if(!readWords.equals("")) {
extractOnlyWordsFromTextFile.add(readWords);
}
readWords ="";
testIfWord = true;
break;
}
}
if(!testIfWord) {
readWords+=(char)byte1;
}
readByteCharByChar = "";
testIfWord = false;
byte1 = (byte)inputStream.read();
if(byte1 == -1 && !readWords.equals("")) {
extractOnlyWordsFromTextFile.add(readWords);
}
}
inputStream.close();
System.out.println(extractOnlyWordsFromTextFile);
System.out.println("The number of words in the choosen text file are: " + extractOnlyWordsFromTextFile.size());
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
This can be done in a very way using Java 8:
Files.lines(Paths.get(file))
.flatMap(str->Stream.of(str.split("[ ,.!?\r\n]")))
.filter(s->s.length()>0).count();
BufferedReader bf= new BufferedReader(new FileReader("G://Sample.txt"));
String line=bf.readLine();
while(line!=null)
{
String[] words=line.split(" ");
System.out.println("this line contains " +words.length+ " words");
line=bf.readLine();
}
The below code supports in Java 8
//Read file into String
String fileContent=new String(Files.readAlBytes(Paths.get("MyFile.txt")),StandardCharacters.UFT_8);
//Keeping these into list of strings by splitting with a delimiter
List<String> words = Arrays.asList(contents.split("\\PL+"));
int count=0;
for(String x: words){
if(x.length()>1) count++;
}
sop(x);
So easy we can get the String from files by method: getText();
public class Main {
static int countOfWords(String str) {
if (str.equals("") || str == null) {
return 0;
}else{
int numberWords = 0;
for (char c : str.toCharArray()) {
if (c == ' ') {
numberWords++;
}
}
return ++numberWordss;
}
}
}