Java subString confusion - java

i was doing a small java code where data is read through a file and stored in a String
and then using subStrig i have to break this string ,
For example data is saved like this "Hello java $" "Hello word $" , each sentence contains $ at the end and i want to break it on the basis of $
I did try using indexOf , lastindexOf etc but was not able to do exact logic , pleas help me
BufferedReader br= new BufferedReader(new FileReader("c:\\javaprograms\\a.txt));
while((a=br.readLine())!=null)
{
s=s+a;
// here i have to split the data that is "Hello java$" "Hello world$"
}

Maybe it would be better to use a Scanner with custom delimiter?
For example like this:
BufferedReader br = new BufferedReader(new FileReader("..."));
Scanner sc = new Scanner(br);
sc.useDelimiter("\\$");
while (sc.hasNext())
{
String text = sc.next();
System.out.println(text);
...
}
This code splits your text with "$" as delimiter

Works fine for me:
String a = "Hello java $ fff";
System.out.println(a.indexOf("$"));
System.out.println(a.substring(0, a.indexOf("$")));
Output:
11
Hello java

You want to look into the split() function in the String class, this will allow you to return an array of Strings split around a particular String or regex.

Related

What am I missing? NumberFormatException error

I want to read from a txt file which contains just numbers. Such file is in UTF-8, and the numbers are separated only by new lines (no spaces or any other things) just that. Whenever i call Integer.valueOf(myString), i get the exception.
This exception is really strange, because if i create a predefined string, such as "56\n", and use .trim(), it works perfectly. But in my code, not only that is not the case, but the exception texts says that what it couldn't convert was "54856". I have tried to introduce a new line there, and then the error text says it couldn't convert "54856
"
With that out of the question, what am I missing?
File ficheroEntrada = new File("C:\\in.txt");
FileReader entrada =new FileReader(ficheroEntrada);
BufferedReader input = new BufferedReader(entrada);
String s = input.readLine();
System.out.println(s);
Integer in;
in = Integer.valueOf(s.trim());
System.out.println(in);
The exception text reads as follows:
Exception in thread "main" java.lang.NumberFormatException: For input string: "54856"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:658)
at java.base/java.lang.Integer.valueOf(Integer.java:989)
at Quicksort.main(Quicksort.java:170)
The file in.txt consists of:
54856
896
54
53
2
5634
Well, aparently it had to do with Windows and those \r that it uses... I just tried executing it on a Linux VM and it worked. Thanks to everyone that answered!!
Try reading the file with Scanner class has use it's hasNextInt() method to identify what you are reading is Integer or not. This will help you find out what String/character is causing the issue
public static void main(String[] args) throws Exception {
File ficheroEntrada = new File(
"C:\\in.txt");
Scanner scan = new Scanner(ficheroEntrada);
while (scan.hasNext()) {
if (scan.hasNextInt()) {
System.out.println("found integer" + scan.nextInt());
} else {
System.out.println("not integer" + scan.next());
}
}
}
If you want to ensure parsability of a string, you could use a Pattern and Regex that.
Pattern intPattern = Pattern.compile("\\-?\\d+");
Matcher matcher = intPattern.matcher(input);
if (matcher.find()) {
int value = Integer.parseInt(matcher.group(0));
// ... do something with the result.
} else {
// ... handle unparsable line.
}
This pattern allows any numbers and optionally a minus before (without whitespace). It should definetly parse, unless it is too long. I don't know how it handles that, but your example seems to contain mostly short integers, so this should not matter.
Most probably you have a leading/trailing whitespaces in your input, something like:
String s = " 5436";
System.out.println(s);
Integer in;
in = Integer.valueOf(s.trim());
System.out.println(in);
Use trim() on string to get rid of it.
UPDATE 2:
If your file contains something like:
54856\n
896
54\n
53
2\n
5634
then use following code for it:
....your code
FileReader enter = new FileReader(file);
BufferedReader input = new BufferedReader(enter);
String currentLine;
while ((currentLine = input.readLine()) != null) {
Integer in;
//get rid of non-numbers
in = Integer.valueOf(currentLine.replaceAll("\\D+",""));
System.out.println(in);
...your code

Accepting formatted Json (multi-line) input from user in a Java console app with Scanner (all lines not being read)

I have a scenario where I need to take formatted Json (multi-line) as an input and do something with it. I figured doing it in a simple console app would be good since it is just a tool I am creating and want it to be able to be ran locally. If I should be reading the Json from a file instead please let me know.
The plan is to have the user paste something like this into a console application and then type "exit".
{
"section1":{
"line1":0.3456,
"line2":{
"line3":45345,
"line4":67567
},
"section2":{
"line6":867867,
"line7":0.16767
},
"section3":{
"line9":9977,
"line10":0.76867
},
"array1":[
{
"ghjf":"1111",
"ggeeaaa":678769,
"ghj":0.6799789
}
]
}
}
exit
A couple of things are happening:
1. The first { is not being recognized so I need to manually insert it.
2. Several lines are not being read... i.e. "line1" is getting skipped and many more.
Here is my code:
System.out.println("Enter a valid JSON string: ");
Scanner scanner = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while (!scanner.nextLine().equals("exit")) {
sb.append(scanner.nextLine());
}
sb.insert(0, "{");
String formattedJson = sb.toString()
.replaceAll("\\t","").replaceAll("\\s", "");
// Do something with formattedJson further in code...
You are calling scanner.nextLine() twice, but only use the value once.
Try declaring it as a variable and only calling nextLine() once:
Scanner scanner = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
String line;
while (!(line = scanner.nextLine()).equals("exit")) {
sb.append(line);
}
As a result, you probably won't need (should remove) this:
sb.insert(0, "{");

Splitting array on new line

I am submitting the following input through stdin:
4 2
30 one
30 two
15 three
25 four
My code is:
public static void main(String[] args) throws IOException {
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String submittedString;
System.out.flush();
submittedString = stdin.readLine();
zipfpuzzle mySolver = new zipfpuzzle();
mySolver.getTopSongs(submittedString);
}
Which calls:
//Bringing it all together
public String getTopSongs(String myString) {
setUp(myString);
calculateQuality();
qualitySort();
return titleSort();
}
Which calls
public void setUp(String myString) {
String tempString = myString;
//Creating array where each element is a line
String[] lineExplode = tempString.split("\\n+");
//Setting up numSongsAlbum and songsToSelect
String[] firstLine = lineExplode[0].split(" ");
numSongsAlbum = Integer.parseInt(firstLine[0]);
songsToSelect = Integer.parseInt(firstLine[1]);
System.out.println(lineExplode.length);
//etc
}
However, for some reason lineExplode.length returns value 1... Any suggestions?
Kind Regards,
Dario
String[] lineExplode = tempString.split("\\n+");
The argument to String#split is a String that contains a regular expression
Your String#split regex will work file on Strings with newline characters.
String[] lineExplode = tempString.split("\n");
The problem is that your tempString has none of these characters, hence the size of the array is 1.
Why not just put the readLine in a loop and add the Strings to an ArrayList
String submittedString;
while (!(submittedString= stdin.readLine()).equals("")) {
myArrayList.add(submittedString);
}
Are you sure the file is using UNIX-style line endings (\n)? For a cross-platform split, use:
String[] lineExplode = tempString.split("[\\n\\r]+");
You should use "\\n" character to separate by new line but check that not all OS use the same separators ( http://en.wikipedia.org/wiki/Newline )
To solve this is very useful the system property line.separator that contains the current separator charater(s) for the current OS that is running the application.
You should use:
String[] lineExplode = tempString.split("\\\\n");
using \n as separator
Or:
String lineSeparator = System.getProperty("line.separator");
String[] lineExplode = tempString.split(lineSeparator);
Using the current OS separator
Or:
String lineSeparator = System.getProperty("line.separator");
String[] lineExplode = tempString.split(lineSeparator + "+");
Using the current OS separator and requiring one item
Its better to use this split this way:
String[] lineExplode =
tempString.split(Pattern.quote(System.getProperty("line.separator")) + '+');
To keep this split on new line platform independent.
UPDATE: After looking at your posted code it is clear that OP is reading just one line (till \n) in this line:
submittedString = stdin.readLine();
and there is no loop to read further lines from input.

Java : replaceAll and .split newline doesn't work

I am wanting to split a line up (inputLine) which is
Country: United Kingdom
City: London
so I'm using this code:
public void ReadURL() {
try {
URL url = new URL("http://api.hostip.info/get_html.php?ip=");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String inputLine = "";
while ((inputLine = in.readLine()) != null) {
String line = inputLine.replaceAll("\n", " ");
System.out.println(line);
}
in.close();
} catch ( Exception e ) {
System.err.println( e.getMessage() );
}
}
when you run the method the the output is still
Country: United Kingdom
City: London
not like it's ment to be:
Country: United Kingdom City: London
now i've tried using
\n,\\n,\r,\r\n
and
System.getProperty("line.separator")
but none of them work and using replace, split and replaceAll but nothing works.
so how do I remove the newlines to make one line of a String?
more detail: I am wanting it so I have two separate strings
String Country = "Country: United Kingdom";
and
String City = "City: London";
that would be great
You should instead of using System.out.println(line); use System.out.print(line);.
The new line is caused by the println() method which terminates the current line by writing the line separator string.
http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedReader.html#readLine()
Read that. readLine method will not return any carriage returns or new lines in the text and will break input by newline. So your loop does take in your entire blob of text but it reads it line by line.
You are also getting extra newlines from calling println. It will print your line as read in, add a new line, then print your blank line + newline and then your end line + newline giving you exactly the same output as your input (minus a few spaces).
You should use print instead of println.
I would advise taking a look at Guava Splitter.MapSplitter
In your case:
// input = "Country: United Kingdom\nCity: London"
final Map<String, String> split = Splitter.on('\n')
.omitEmptyStrings().trimResults().withKeyValueSeparator(": ").split(input);
// ... (use split.get("Country") or split.get("City")

string tokenizer wrong usage in java

I believe I am not using correctly String Tokenizer. Here is my code:
buffer = new byte[(int) (end - begin)];
fin.seek(begin);
fin.read(buffer, 0, (int) (end - begin));
StringTokenizer strk = new StringTokenizer(new String(buffer),
DELIMS,true);
As you can see I am reading a chunk of lines from a file(end and begin are line numbers) and I am transfering the data to a string tokenizer. My delimitators are:
DELIMS = "\r\n ";
because I want to separate words that have a space between them, or are on the next line.
However this code sometimes separates whole words also. What could be the explanation?? Is my DELIMS string conceived wrong?
Also I am passing "true" as an argument to the tokenizer because I want the delimitators to be treated as tokens as well.( I want this because I want to count the line I am currently at)
Could you please help me. Thanks a lot.
To start with, your method for converting bytes into a String is a bit suspect, and this overall method will be less-than-efficient, especially for a larger file.
Are you required to use StringTokenizer? If not, I'd strongly recommend using Scanner instead. I'd provide you with an example, but will ask that you just refer to the Javadocs instead, which are quite comprehensive and already contain good examples. That said, it accepts delimiters as well - but as Regular Expressions, so just be aware.
You could always wrap your input stream in a LineNumberReader. That will keep track of the line number for you. LineNumberReader extends BufferedReader, which has a readLine() method. With that, you could use a regular StringTokenizer to get your words as tokens. You could use regular expressions or Scanner, but for this case, StringTokenizer is simpler for beginners to understand and quicker.
You must have a RandomAccessFile. You didn't specify that, but I'm guessing based on the methods you used. Try something like:
byte [] buffer = ...; // you know how to get this.
ByteArrayInputStream stream = new ByteArrayInputStream(buffer);
// if you have java.util.Scanner
{
int lineNumber = 0;
Scanner s = new Scanner(stream);
while (s.hasNextLine()) {
lineNum++;
String line = s.nextLine();
System.out.format("I am on line %s%n", lineNum);
Scanner lineScanner = new Scanner(line);
while (lineScanner.hasNext()) {
String word = lineScanner.next();
// do whatever with word
}
}
}
// if you don't have java.util.Scanner, or want to use StringTokenizer
{
LineNumberReader reader = new LineNumberReader(
new InputStreamReader(stream));
String line = null;
while ((line = reader.nextLine()) != null) {
System.out.println("I am on line " + reader.getLineNumber());
StringTokenizer tok = new StringTokenizer(line);
while (tok.hasMoreTokens()) {
String word = tok.nextToken();
// do whatever with word
}
}
}

Categories