I'm converting a C prog that parses a text string and produces human readable o/p.
Got it nearly done, but having a problem understanding the difference in
*char_ptr++
and
char_ptr-- in
token[i++] = c = toupper(*char_ptr++);
if (c == '\0')
{
char_ptr--;
return( 0 );
}
Am I correct in thinking that *char_ptr++ will effectivley point to the next char in the 'string'?
If so, what does char_ptr-- do?
Thanks.
Regard *char_ptr++ as:
char tmp = *char_ptr;
char_ptr++;
c = toupper(tmp);
So it effectively fetches the current character, and advances the pointer by one. Because the ++ operator has a higher precedence than the unary *, such an expression is evaluated in the order *(char_ptr++).
The incrementation is applied first, but since the postfix ++ operator returns the result prior to the manipulation, the * dereferencing operator is applied on the old address.
char_ptr-- simply decreases the pointer by one.
In the same way as ++ increments the pointer and points to the next character, -- decrements it, pointing to the previous character. In this case, it puts it back to the last real character from the terminating null.
Because you're converting to java, you're going to have to remove the pointers, Java doesn't support them.
token[i++] = c = toupper(*char_ptr++);
if (c == '\0')
{
char_ptr--;
return( 0 );
}
Likely had some sort of declaration above it saying:
char* char_ptr = some_array;
Instead, that'll be
int pos = 0;
And the above code becomes:
token[i++] = c = toupper(some_array[pos++]);
if (c == '\0')
{
pos--;
return( 0 );
}
Yes, you are correct. It's a way of "peeking" ahead into the "string" and then returning to where you were if the string was at it's end.
This question is solved by precedence rules. The expression
*char_ptr++
is resolved to
*(char_ptr++)
meaning "The character after the character that ptr is pointing to". So when c equals a '\0' (zero), the pointer gets decremented, so it points to the previous character. It practically decrements to the previous character whenever there's a 0 encountered, so that char_ptr points to whatever it pointed to during the last run of the block.
Related
This question already has answers here:
What does "|=" mean? (pipe equal operator)
(6 answers)
Closed 7 years ago.
int equal = 0;
for (int i = 0; i < a.length(); i++) {
equal |= a.charAt(i) ^ b.charAt(i);
}
return equal == 0;
I understand pipe and XOR operator But what is |= doing?
It is similar to +=. See the table here
|= bitwise inclusive OR and assignment operator C |= 2 is same as C = C | 2
So it is equivalent to writing your code as:
equal = equal | a.charAt(i) ^ b.charAt(i)
Also as luk2302 has pointed out correctly, that there (bitwise exclusive OR)^ has higher precedence over (bitwise inclusive OR)| so you can include it inside the brackets like this:
equal = equal | (a.charAt(i) ^ b.charAt(i))
Diatribe
This code is appears to be a great example of why goofballs should not be hired as programmers.
Answer
Here is an explanation of the code:
Start with two strings, which are presumed to be the same length.
Perform an xor operation on two characters.
"Add" the result of the xor operation to an accumulator (named equal; as an aside, in context I prefer the even less obvious variable name artificialSweetener) using the or-equals operator.
If not at the end of string a, repeat starting at step 2 above.
If, after the loop completes, the value of the equal (or artificialSweetener as you wish) operator is zero, then return true. Else return false.
Notes
The or-equals operator performs a bitwise or operation between the left hand argument and the right hand argument then assigns the result to the left hand argument. This means that this statement:
left |= right
performs the same work as this statement:
left = (left | right)
Why the Anger
It is common for goofballs to regularly reinvent already existing functionality and to do it poorly. In this sense, the code above is a success; it both reinvents existing functionality and does it terribly.
This code exhibits some disturbingly incompetent behaviour
It continues performing comparison even after a difference has been found.
It will throw value-free NullPointerExceptions if a and/or b are null.
It has the benefit of being not at all obvious to a newer java programmer.
It throws an exception if string b is shorter in length than string a.
It returns a false positive when string a is an initial subset of string b. For example, a = "Blah" and b = "BlahNotAtAllEqual" will result in a false positive.
What would a competent programmer do
A programmer who is not an idiot would perform a string comparison operation using the String.equals method or, if they are more than just barely competent, they would use a utility like the Apache Commons Lang StringUtils to perform null safe comparisons.
It's simple mate. The following lines do the same thing:
equal |= a.charAt(i) ^ b.charAt(i);
equal = equal | (a.charAt(i) ^ b.charAt(i));
While I was creating a program to compress a string I ran into this strange problem, I will paste the code snippets with their outputs, I would like someone to clearly explain why this is happening.
The first code snippet: here if same letter appears consecutively, then the successive occurrences of the letter is replaced by the total count of same letters. Ex: aaabbb should be written as a3b3.
public static String compress(String str){
String compressed = "";
char prev = str.charAt(0);
int count = 1;
for (int i = 1; i < str.length(); i++) {
char curr = str.charAt(i);
if (curr == prev) { // in case curr is equal to prev
count++;
} else { // in case curr is not equal to prev
//compressed=compressed+prev+count;
compressed+=prev+count; // Shorthand used here
count=1;
prev=curr;
}
}
compressed=compressed+prev+count; // Shorthand not used
System.out.println(compressed);
return compressed;
}
the output for this above code when inputted with aabbccaabbccaabbccaabb is 99100101991001019910010199b2, observe the last two elements of the output, this is because outside the loop, shorthand is not used. If I write the expression as compressed = compressed +prev+count inside the loop, I'll get the intended output.
I thought this output is because the operation is messing with the address of the String. But the next code confused me again.
String prev= "abc";
String curr = "def";
String result="";
result+=prev+curr;
System.out.println(result);
I think this is because the right hand operation is performing an ASCII addition, I cannot come to a conclusion, can anyone clarify.
I am sleep deprived and hence I am not able to come to a conclusion, hence asking someone to clarify my trivial doubt.
It has nothing to do with the reference. When you did prev+count ascii value of the character in prev is added with the integer count. In this case :
ascii of "a" is 97, and it occurred twice... so 97 +2 = 99 ..
ascii of "b" is 98, and it occurred twice... so 98 +2 = 100 ..
ascii of "c" is 99, and it occurred twice... so 99 +2 = 101 ..
that's why the output is 99100101991001019910010199100
try this : compressed+=(""+prev)+count; // Shorthand used here
In this case, or in compressed+=""+prev+count case, since the operation happens from left to right, the + operator is applied on a string ("") and char(prev) and behaves like append and also returns a string. The resulting string is then appened with another int (prev)
A better way is using a StringBuilder
Take a look at this subject and at JLS 15.18.1 section :
You see this behavior as a result of the combination of operator
precedence and string conversion.
JLS 15.18.1 states:
If only one operand expression is of type String, then string conversion (ยง5.1.11) is performed on the other operand to produce a
string at run time.
Therefore the right hand operands in your first expression are
implicitly converted to string: string = string + ((char)65) + 5;
For the second expression however string += ((char)65) + 5; the +=
compound assignment operator has to be considered along with +.
Since += is weaker than +, the + operator is evaluated first.
There we have a char and an int which results in a binary numeric
promotion to int. Only then += is evaluated, but at this time
the result of the expression involving the + operator has already been evaluated.
Whenever you add a char to an int in java first it converts the character into its equivalent ASCII value and then adds it to the integer
eg suppose the following scenario ,
char c = 'a'; // ASCII value of 'a' is 97
int i = c + 5 ; // result will be 97 + 5 = 102
I think this answers your first half question
Now the Second part ,
Whenever you use the shorthand operator in Java the expression at right hand side is evaluated first.
Hence , for expresion
result += prev + curr it is evaluated as
result = result + (prev + curr);
Therefore ,
result+=prev+curr; // Here first it appends "abc" with "def" and then the resultant "abcdef" is appended to as result .
you can convert your charater value "prev" to string and than append count to it.
compressed += Character.toString(prev) + count;
I tried the below, but Eclipse throws an error for this.
while((s.charAt(j)== null)
What's the correct way of checking whether a character is null?
Check that the String s is not null before doing any character checks. The characters returned by String#charAt are primitive char types and will never be null:
if (s != null) {
...
If you're trying to process characters from String one at a time, you can use:
for (char c: s.toCharArray()) {
// do stuff with char c
}
(Unlike C, NULL terminator checking is not done in Java.)
Default value to char primitives is 0 , as its ascii value.
you can check char if it is null. for eg:
char ch[] = new char[20]; //here the whole array will be initialized with '\u0000' i.e. 0
if((int)ch[0]==0){
System.out.println("char is null");
}
Correct way of checking char is actually described here.
It states:
Change it to: if(position[i][j] == 0)
Each char can be compared with an int.
The default value is '\u0000' i.e. 0 for a char array element.
And that's exactly what you meant by empty cell, I assume.
You can use the null character ('\0'):
while((s.charAt(j)=='\0')
I actually came here from reading a book "Java: A Beginner's Guide" because they used this solution to compare char to null:
(char) 0
Because in ASCII table, null is at the position of 0 in decimal.
So, solution to OP's problem would be:
while((s.charAt(j) == (char) 0)
I also tried out the already offered solution of:
while((s.charAt(j)=='\0')
And it also worked.
But just wanted to add this one too, since no one mentioned it.
If s is a string and is not null, then you must be trying to compare "space" with char. You think "space" is not a character and space is just null, but truth is that space is a character. Therefore instead of null, use (which is a space) to compare to character.
I currently have the following code for java.
public class lesson8
{
static Console c; // The output console
public static void main (String[] args)
{
c = new Console ();
String user;
int length, counter, spacecounter;
spacecounter=0;
c.print("Enter a string. ");
user = c.readLine();
length = (user.length()-1);
for (counter=0;counter<length;counter++)
{
if (user.charAt(counter) = "")
{
spacecounter++;
}
}
c.println("There are "+spacecounter+" spaces in your string.");
c.println("There are "+counter+" characters in your string.");
// Place your program here. 'c' is the output console
// main method
}
}
I am getting an error on this part:
if (user.charAt(counter) = "")
The error is
The left-hand side of an assignment must be a variable.
I changed it to "==", but now I get another error:
The type of the left sub-expression "char" is not compatible with the type of the right sub-expression "java.lang.String".
How would I solve this?
Thanks!
So, the reason why
if (user.charAt(counter) = "")
gives that error is that "=" is an assignment operator in java, and so the left-hand side must be a variable. That being said, you probably actually want
if (user.charAt(counter) == ' ')
which uses the comparison operator (==) and the space character (' '). ("" is an empty string)
You are using an asignment over a comparison operator.
Change
if (user.charAt(counter) = "")
to
if (user.charAt(counter) == "")
Update:
You also have an error at comparison again.
You should also use single quotes ( ' ) to compare a char, otherwise it won't get compiled.
if (user.charAt(counter) == '')
But this too will not get compiled as a zero length char is not defined.
You should be comparing a valid character, say ' ' for space.
You want to use the equality operator ==, not the assignment operator = .
"==" is going to make sure that the value to the right is the same as the variable to the left.
"=" is an assignment operator and is used to give value TO the variable, rather than compare it.
I got same error in my code. Adding parenthesis solved this error
Changed from
if(isNotNullorEmpty(operator))
ArrayList<String> result = getOperatorAndTypeforName(name );
to
if(isNotNullorEmpty(operator)){
ArrayList<String> result = getOperatorAndTypeforName(name );
}
I'm curious why the String.indexOf is returning a 0 (instead of -1) when asking for the index of an empty string within a string.
The Javadocs only say this method returns the index in this string of the specified string, -1 if the string isn't found.
To me this behavior seems highly unexpected, I would have expected a -1. Any ideas why this unexpected behavior is going on? I would at the least think this is worth a note in the method's Javadocs...
System.out.println("FOO".indexOf("")); // outputs 0 wtf!!!
System.out.println("FOO".indexOf("bar")); // outputs -1 as expected
System.out.println("FOO".indexOf("F")); // outputs 0 as expected
System.out.println("".indexOf("")); // outputs 0 as expected, I think
The empty string is everywhere, and nowhere. It is within all strings at all times, permeating the essence of their being, yet as you seek it you shall never catch a glimpse.
How many empty strings can you fit at the beginning of a string? Mu
The student said to the teacher,
Teacher, I believe that I have found the nature of the empty string. The empty string is like a particle of dust, and it floats freely through a string as dust floats freely through the room, glistening in a beam of sunlight.
The teacher responded to the student,
Hmm. A fine notion. Now tell me, where is the dust, and where is the sunlight?
The teacher struck the student with a strap and instructed him to continue his meditation.
Well, if it helps, you can think of "FOO" as "" + "FOO".
int number_of_empty_strings_in_string_named_text = text.length() + 1
All characters are separated by an empty String. Additionally empty String is present at the beginning and at the end.
By using the expression "", you are actually referring to a null string. A null string is an ethereal tag placed on something that exists only to show that there is a lack of anything at this location.
So, by saying "".indexOf( "" ), you are really asking the interpreter:
Where does a string value of null exist in my null string?
It returns a zero, since the null is at the beginning of the non-existent null string.
To add anything to the string would now make it a non-null string... null can be thought of as the absence of everything, even nothing.
Using an algebraic approach, "" is the neutral element of string concatenation: x + "" == x and "" + x == x (although + is non commutative here).
Then it must also be:
x.indexOf ( y ) == i and i != -1
<==> x.substring ( 0, i ) + y + x.substring ( i + y.length () ) == x
when y = "", this holds if i == 0 and x.substring ( 0, 0 ) == "".
I didn't design Java, but I guess mathematicians participated in it...
if we look inside of String implementation for a method "foo".indexOf(""), we arrive at this method:
public int indexOf(String str) {
byte coder = coder();
if (coder == str.coder()) {
return isLatin1() ? StringLatin1.indexOf(value, str.value)
: StringUTF16.indexOf(value, str.value);
}
if (coder == LATIN1) { // str.coder == UTF16
return -1;
}
return StringUTF16.indexOfLatin1(value, str.value);
}
If we look inside of any of the called indexOf(value, str.value) methods we find a condition that says:
if the second parameter (string we are searching for) length is 0 return 0:
public static int indexOf(byte[] value, byte[] str) {
if (str.length == 0) {
return 0;
}
...
This is just defensive coding for an edge case, and it is necessary because in the next method that is called to do actual searching by comparing bytes of the string (string is a byte array) it would otherwise have resulted in an ArrayIndexOutOfBounds exception:
public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
byte first = str[0];
...
This question is actually two questions:
Why should a string contain the empty string?
Why should the empty string be found specifically at index zero?
Answering #1:
A string contains the empty string in order to be in accordance with Set Theory, according to which:
The empty set is a subset of every set including itself.
This also means that even the empty string contains the empty string, and the following statement proves it:
assert "".indexOf( "" ) == 0;
I am not sure why mathematicians have decided that it should be so, but I am pretty sure they have their reasons, and it appears that these reasons can be explained in layman's terms, as various youtube videos seem to do, (for example, https://www.youtube.com/watch?v=1nBKadtFViM) although I have not actually viewed any of those videos, because #AintNoBodyGotNoTimeFoDat.
Answering #2:
The empty string can be found specifically at index zero of any string, because why not? In other words, if not at index zero, then at which index? Index zero is as good as any other index, and index zero is guaranteed to be a valid index for all strings except for the trifling exception of the empty string.