Reading string from raw txt file - java

I have a raw txt file with delimiters which i use to split text. To receive text I use scanner:
int textid = getResources().getIdentifier(word, null, this.getPackageName());
Scanner ch = new Scanner(getResources().openRawResource(textid));
Opened file is correct. When I begin receiving information I need to read it until "$" is got.
while (ch.hasNext()) {
str = ch.next();
boolean flag = (str.equals("$"));
while (!(str.equals("$"))) {
str = ch.next();
}
The problem is that when str equals "$" (Checked it through breakpoint) flag equals "false". However, if I initialize String m = "$" and check flag = m.equals("$")flag equals "true". Also tried to use str != "$" but it didn't help.
My guess is that scanner.next() returns another type but it seems to be rather strange.

This might help you.
First next() reads multiple characters until whitespace is found.
Go through every char in str to see if its the '$'. Then when you find it do whatever you wanted to do.
while (ch.hasNext()) {
String str = ch.next();
for(int i = 0; i<str.length(); i++) {
if(str.charAt(i) == '$') {
//do something
}
}
}

When your code reads a "$", it will break the inner loop. When it starts over the outer loop, you're calling ch.next() again, which overwrites the previous "$"in str. This might be the reason why flag is set to false. It would detect the "$" only if it's the first thing in the file.
Also, you might want to check ch.hasNext() in the inner loop again.

Related

String not populating properly

I am writing a program that is going to read a string from a file, and then remove anything that isn't 1-9 or A-Z or a-z. The A-Z values need to become lowercase. Everything seems to run fine, I have no errors, however my output is messed up. It seems to skip certain characters for no reason whatsoever. I've looked at it and tweaked it but nothing works. Can't figure out why it is randomly skipping certain characters because I believe my if statements are correct. Here is the code:
String dataIn;
int temp;
String newstring= "";
BufferedReader file = new BufferedReader(new FileReader("palDataIn.txt"));
while((dataIn=file.readLine())!=null)
{
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
i++;
}
System.out.println(newstring);
}
So to give you an example, the first string I read in is :
A sample line this is.
The output after my program runs through it is this:
asmlietis
So it is reading the A making it lowercase, skips the space like it is suppose to, reads the s in, but then for some reason skips the "a" and the "m" and goes to the "p".
You're incrementing i in the each of the blocks as well as in the main loop "header". Indeed, because you've got one i++; in an else statement for the last if statement, you're sometimes incrementing i twice during the loop.
Just get rid of all the i++; statements other than the one in the for statement declaration. For example:
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
}
I wouldn't stop editing there though. I'd also:
Use a char instead of an int as the local variable for the current character you're looking at
Use character literals for comparisons, to make it much clearer what's going on
Use a StringBuilder to build up the string
Declare the variable for the output string for the current line within the loop
Use if / else if to make it clear you're only expecting to go into one branch
Combine the two paths that both append the character as-is
Fix the condition for numbers (it's incorrect at the moment)
Use more whitespace for clarity
Specify a locale in toLower to avoid "the Turkey problem" with I
So:
String line;
while((line = file.readLine()) != null)
{
StringBuilder builder = new StringBuilder(line.length());
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
// Are you sure you want to trim 0?
if ((current >= '1' && current <= '9') ||
(current >= 'a' && current <= 'z')) {
builder.append(current);
} else if (current >= 'A' && current <= 'Z') {
builder.append(Character.toLowerCase(current, Locale.US));
}
}
System.out.println(builder);
}

How to print several strings backwards in Java

I am trying to take a file full of strings, read it, then print out a few things:
The string
The string backwards AND uppercase
The string length
There are a few more things, however I haven't even gotten to that point and do not want to ask anyone to write the code entirely for me. After messing around with it for a while, I have it almost completed (I believe, save for a few areas).
The piece that is tripping me up is the backwards word. We are required to put our output neatly into columns using prinf, but I cannot do this if I read each char at a time. So I tried setting a String backwardsWord = ""; and adding each character.
This is the piece that is tripping me up:
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
My issue is that when I print it, the first word works properly. However, each word after that is added to the previous word.
For example: if I am printing cat, dog, and rat backwards, it shows
TAC
TACGOD
TACGODTAR
I obviously want it to read
TAC
GOD
TAR
Any help would be appreciated.
It looks like your variable backwardsWord is always appending a character without being reset between words. The simplest fix is to clear the backwardsWord just before your loop by setting it to empty string.
backwardsWord = ""; //Clear any existing characters from backwardsWord
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
If you are building up a String one character at a time you will be using a lot of memory because Java Strings are immutable.
To do this more efficiently use a StringBuilder instead. This is made for building up characters like what you are doing. Once you have finished you can use the toString method to get the String out.
StringBuilder builder = new StringBuilder(); //Creates the String builder for storing the characters
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
builder.append(upperCaseWord.charAt(i)); //Append the characters one at a time
}
backwardsWord = builder.toString(); //Store the finished string in your existing variable
This has the added benefit of resetting the backwardsWord each time.
Finally, since your goal is to get the String in reverse we can actually do it without a loop at all as shown in this answer
backwardsWord = new StringBuilder(upperCaseWord).reverse().toString()
This creates a new StringBuilder with the characters from upperCaseWord, reverses the characters then stores the final string in backwardsWord
Where are you declaring the String backwardsWord?
If you don't clear it between words then the memory space allocated to that string will still contain the previously added characters.
Make sure you are tossing in a backwardsWord = ""; in between words to reset it's value and that should fix your problem.
Without seeing more of your code I can't tell you exactly where to put it.
This should do the job ->
class ReverseWordsInString{
public static String reverse(String s1){
int l = s1.length();
if (l>1)
return(s1.substring(l-1) + reverse(s1.substring(0,l-1)));
else
return(s1.substring(0));
}
public static void main(String[] args){
String st = "Cat Dog Rat";
String r = "";
for (String word : st.split(" "))
r += " "+ reverse(word.toUpperCase());
System.out.println("Reversed words in the given string: "+r.trim());
}
}

Efficent way to replace underscore with char or string

I have researched this topic for a while, but without much success. I did find the StringBuilder and it works wonders, but that's as far as I got. Here is how I got my hangman program to work like it should:
if(strGuess.equalsIgnoreCase("t")){
mainword.replace(0,1,"T");
gletters.append('T');
}
else if(strGuess.equalsIgnoreCase("e")){
mainword.replace(1,2,"E");
gletters.append('E');
}
else if(strGuess.equalsIgnoreCase("c")){
mainword.replace(2,3,"C");
gletters.append('C');
}
else if(strGuess.equalsIgnoreCase("h")){
mainword.replace(3,4,"H");
gletters.append('H');
}
else if(strGuess.equalsIgnoreCase("n")){
mainword.replace(4,5,"N");
gletters.append('N');
}
else if(strGuess.equalsIgnoreCase("o")){
mainword.replace(5,6,"O");
mainword.replace(7,8,"O");
gletters.append('O');
}
else if(strGuess.equalsIgnoreCase("l")){
mainword.replace(6,7,"L");
gletters.append('L');
}
else if(strGuess.equalsIgnoreCase("g")){
mainword.replace(8,9,"G");
gletters.append('G');
}
else if(strGuess.equalsIgnoreCase("y")){
mainword.replace(9,10,"Y");
gletters.append('Y');
}
else{
JOptionPane.showMessageDialog(null, "Sorry, that wasn't in the word!");
errors++;
gletters.append(strGuess.toUpperCase());
}
SetMain = mainword.toString();
GuessedLetters = gletters.toString();
WordLabel.setText(SetMain);
GuessedLabel.setText(GuessedLetters);
GuessText.setText(null);
GuessText.requestFocusInWindow();
However, I can't do this for EVERY letter for EVERY word, so is there a simple and efficient way to do this? What I want is to have a loop of some sort so that I would only have to use it once for whatever word. So the word could be technology (like it is above) or apple or pickles or christmas or hello or whatever.
I have tried using a for loop, and I feel the answer lies in that. And if someone could explain the charAt() method and how/where to use it, that'd be good. The closest I got to being more efficient is:
for(i = 0; i < GuessWord.length(); i++) {
if (GuessWord.charAt(i) == guess2) {
mainword.replace(i,i,strGuess.toUpperCase());
}
So if you could use that as a basis and go off of it, like fix it? Or tell me something I haven't thought of.
It's a good question. There's clearly repeated code, so how do you replace all that with something reusable. Actually, you can dispense with all of your code.
That whole code block can be replaced by just one line (that works for every word)!
String word = "TECHNOLOGY"; // This is the word the user must guess
mainword = word.replaceAll("[^" + gletters + "]", "_");
This uses replaceAll() with a regex that means "any letter not already guessed" and replaces it with a underscore character "_". Note that Strings are immutable, and the replaceAll() method returns the modified String - it doesn't modify the String called on.
Here's some test code to show it in action:
public static void main(String[] args) {
String word = "TECHNOLOGY"; // what the user must guess
StringBuilder gletters = new StringBuilder("GOTCHA"); // letters guessed
String mainword = word.replaceAll("[^" + gletters + "]", "_");
System.out.println(mainword);
}
Output:
T_CH_O_OG_

Is this a good way of parsing a string?

My program reads lines from a plain text file w/ lines formatted: <integer>;<integer>%n, where ; is the delimiter. It compares the two parsed integers against 2 other known values and increments tallyArray[i] if they match.
I currently use:
try {
scan = new Scanner(new BufferedReader(new FileReader("LogFileToBeRead.txt")));
for (int i = 0; i < tallyArraySize; i++) {
explodedLogLine = scan.nextLine().split(";");
if (IntReferenceVal1 == Integer.parseInt(explodedLogLine[0]) && IntReferenceVal2 == Integer.parseInt(explodedLogLine[1])) {
tallyArray[i]++;
}
}
} finally {
if (scan != null) { scan.close(); }
}
I was wondering if there were any serious faults with this method. It does not need to be production-quality.
Also, is there a standard way of parsing a string like this?
EDIT: We can assume the text file is perfectly formatted. But I see the importance for accounting for possible exceptions.
You are not handling NumberFormatExceptions thrown by the Integer.parseInt() method calls. If there's one bad line, execution exits your for loop.
You aren't vetting the integrity of the file you are reading from. If there isn't a ; character or if the Strings aren't actually numbers, execution simply exits the code block you posted.
If you can assume the file is perfectly formatted, and you're set on using a Scanner, you can add ; as a delimiter to the Scanner:
scan = new Scanner(new BufferedReader(new FileReader("LogFileToBeRead.txt")));
scan.useDelimiter(Pattern.compile("(;|\\s)"));
for (int i = 0; i < tallyArraySize; i++) {
int ref1 = scan.nextInt();
int ref2 = scan.nextInt();
if (IntReferenceVal1 == ref1 &&
IntReferenceVal2 == ref2) {
tallyArray[i]++;
}
}
And simply call Scanner.nextInt() twice for each line.
According to me There are three flaws in the program.
Delimiter ; what if there is delimiter is removed by accident or added by accident
There should be check on explodedLogLine that it is of length 2 and it is not null otherwise it will result in unexpected runtime error
You should catch NumberFormatException format exception since you can never be sure that Input is always a number
A simple illustration below gives you idea how things will go wrong.
String str = "3;;3";
System.out.println(Arrays.toString(str.split(";")));
This code will print [3, , 3] in such case your program will produce NumberFormatException as "" string can not be parsed to Integer.

How to find EOF in a string in java?

I am working in school project. In that what they told is, I will be given a String which contains an actual program like....
import java.io.*\npublic class A{\n...........EOF
And My job is to find particular regular expressions in that String(Program).
Now My question is..
void myFunc(String s)
{
while(s.charAt(i) != EOF) /*needed replacement for EOF*/
{
// Actual Code
}
}
In the above code, how to find whether EOF is reached in a string?
It's unlikely that you need this - you probably just need to read till the end of the string, and since it's a representation of a file's contents, your teacher referred to it as EOF.
However...
There is a character called EOF. It's also called control-Z, because that's how you type it. If you want to include it in a string, you have to type it as "\u001a" as in:
String iHaveAnEof = "file ends here\u001a";
If you really need this, your teacher is probably older than me, and I'm probably old enough to be your grandfather ;-)
There is no EOF character in a string. You just need to iterate over the characters in the string:
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
//Process char
}
BufferedReader rd=new BufferedReader(new InputStreamReader(new FileInputStream("Input.txt"),"UTF-8"));
char ch;
int r;
while(true)
{
r=rd.read(); //Reading a character in integer format
if(r==-1) //Checking for the End of File
break;
else
{
ch=(char)r; //Converting to char format
System.out.println(ch);
}
}

Categories

Resources