C++: Pointer assignment warning on strchr() - c++

I get the error assignment makes pointer from integer without a cast on the following code, what does it mean?
char * splitter;
if(splitter = strchr(key, ':') != NULL && *(splitter + 1) == ' ')

It is because of the priority of operations. You need to put an extra set of parens to make sure it happens in the right order:
char * splitter;
if((splitter = strchr(key, ':')) != NULL && *(splitter + 1) == ' ')
otherwise the it will evaluate as this:
splitter = (strchr(key, ':') != NULL)
Since strchr(key, ':') != NULL will evaluate to either a 1 or a 0, in your example, you are assigning an integer to a pointer type, hence the warning.
however, i would just write it as in your second example, since it is simpler and less error prone. Making it one line shorter doesn't add anything except complexity.

The not-equal operator != has higher precedence than the assignment operator =, so your original line reads like splitter = (strchr(key, ':') != NULL) rather than your intended (splitter = strchr(key, ':)) != NULL, so the compiler tries to assign to splitter the result of the comparison between strchr() and NULL.

The != operator has a higher precedence than the = operator. That means your expression splitter = strchr(key, ':') != NULL is actually interpreted as splitter = (strchr(key, ':') != NULL).
Put the assignment into parentheses to increase the precedence of that part:
(splitter = strchr(key, ':')) != NULL

The != has higher precendence than the =. You should fully parenthesize:
if (((splitter = strchr(key, ':')) != NULL) && (*(splitter + 1) == ' '))

Related

Time complexity for Regular Expression Matching

I was solving the problem Regular Expression Matching on leetcode. I solved it using recursion as below:
if (p.empty()) return s.empty();
if ('*' == p[1])
// x* matches empty string or at least one character: x* -> xx*
// *s is to ensure s is non-empty
return (isMatch(s, p.substr(2)) || !s.empty() && (s[0] == p[0] || '.' == p[0]) && isMatch(s.substr(1), p));
else
return !s.empty() && (s[0] == p[0] || '.' == p[0]) && isMatch(s.substr(1), p.substr(1));
But in this how can I find the time complexity of the code?
Problem link: https://leetcode.com/problems/regular-expression-matching/
PS: In solution they have explained the time complexity but I could not understand that.
Assume T(t,p) is the time complexity of function isMatch(text, pattern) where t is text.length() and p is pattern.length() / 2
First T(x,0) = 1 for all x
Then if pattern[1] == '*', T(t,p) = T(t,p-1) + T(t-1,p) + O(t + p)
Otherwise T(t,p) = T(t-1, p-0.5) + O(t + p)
Obviously the first case is worse
Think about the Combination Meaning of T.
Originally the is a ball you on coordinate (t,p), in one step you can move it to (t-1,p) or (t,p-1), costing t+p.
The ball stop on axis.
Then T(t,p) equals to the total cost of each valid way to move the ball to axis starting from (t,p).
Then we know
So the total time complexity is O((t+p)2^(t + p/2))
BTW your code will run faster if you use something like std::string_view instead of .substr(), which prevents copying the whole string.

While loop going past limit

while (('\0' != *str1) && ('\0' != *str2) &&
(false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2)) {
++str1;
++str2;
}
This code keeps looping even past the NULL terminator.
There must be something incredibly obvious I am missing here, but I simply cannot see it.
If either one of those chunks of code between the && gets evaluated as false, it should break, but it does not do so and keeps parsing the string even past the NULL terminator into gibberish.
while (('\0' != *str1) && ('\0' != *str2) &&
(false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2))
The ternary operator ?: has lower precedence than nearly all other operators, including the logical AND &&. So, the &&s get applied first, and thus what you are saying here is:
if str1 is not at its NUL terminator, && str2 is not at its own, && we are not comparing case-sensitively,
then ? loop while the strings' current characters are equal case-insensitively,
else : loop while the strings' current characters are equal exactly.
Therefore, you will loop forever if the strings are equal, or at least past their NUL terminators and into Undefined Behaviour Land.
What you instead mean is this, where we wrap the entire ternary expression in parentheses, to override its default precedence and thus make the language evaluate it as the 3rd condition of the &&:
while ( *str1 != '\0' && *str2 != '\0' &&
(!sensi ? std::toupper(*str1) == std::toupper(*str2) : *str1 == *str2) )
i.e. to loop while:
str1 is not at its NUL terminator, &&
str2 is not at its own, &&
( the strings' current characters are equal in ?: the way specified by sensi ).
I would suggest to review operator precedence here, not overuse parentheses where redundant, and not use Yoda conditionals. Also, this large compound condition could perhaps best be expressed as a separate function taking the 2 strs as input and checking each condition separately, to avoid confusing long logical tests.

Comparison between pointer and integer in string class - C++

I'm new to C++.
string str = "WWWHBBB";
if(str[mid] == "H" && str[0] != "W") return; // corrected after comments for second operand
The above line with if condition gives me an error.
Comparison between pointer and integer ('std::__1::basic_string, std::__1::allocator >::value_type' (aka 'char') and 'const char *')
I have searched the internet enough to know that array style access is fine in strings. Error basically is pointing out comparison about pointer and integer. Really? I thought I was comparing character H to another character in string str.
I tried if str[mid] really returns an iterator I should do *str[mid]. Nah! Didn't work either.
In the expression of the if statement
if(str[mid] == "H" && str[mid] != "W") return;
the string literals "H" and "W" that have the type const char[2] are implicitly converted to pointers to their first characters of the type const char *.
So you are trying to compare a character returned by the expression str[mid] with a pointer.
Instead of the string literals you need to use character literals like to compare characters
if(str[mid] == 'H' && str[mid] != 'W') return;
You could also write like
if(str[mid] == *"H" && str[mid] != *"W") return;
or
if(str[mid] == "H"[0] && str[mid] != "W"[0]) return;
dereferencing the pointers but this will be confusing
Pay attention to that if str[mid] == 'H' then the second operand will always yield true. So it is enough to write
if( str[mid] == 'H' ) return;
You'd want to compare with a single char
if (str[mid] == 'H' && str[mid] != 'W') return;
Note that double-quotes in this case refer to a const char[] whereas single-quotes refer to a single char.
The warning is telling you that the only way to make those comparisons in your case would be to compare the lhs char (result of str[mid]) to the rhs would be to let the array decay to const char* and compare the pointer address to the char.

Pointer + Number

I have this code:
How can i debug with printf?
char *string = "something";
short i;
i = strlen(string);
while (i-- && (*(string+i)==' ' || *(string+i)=='\0'));
*(string+i+1) = '\0' ;
What does this do?
*(string+i)
According to the C standard, the expression e1[e2] is by definition equivalent to *(e1+e2). So when you write
*(string + i)
it is equivalent
string[i]
This definition has an interesting side effect that it is actually correct to write 3[s] instead of s[3] as operator [] is commutative.
*(string+i) is string[i]. So *(string+i) == '\0' is the same as string[i] == 0.
This is because pointer + number is the same address as pointer + number * sizeof(type) (in your case string + i is the same a string + i * sizeof(char). When you index into an array arr[i] is the element at address arr + i * sizeof(type).
To debug with printf you simply insert printf statements and poke around the content of variables. For example:
char *string = "something";
short i;
i = strlen(string);
printf("Debug i = %d\n", i);
The postfix operator -- means that i will get evaluated and then decremented before the next sequence point.
The && operator has a sequence point between the left and right operand, so i-- occurs before the right operand is evaluated.
Therefore string+i refers to the value of the original i - 1.
*(string+i) is guaranteed to be completely equivalent with string[i]. The former is just a less readable form.
The code does a peculiar check. If a character is the null terminator, it adds another null terminator behind the first one. That doesn't make any sense. Only the check for space makes some sense.
I also doubt the true intention is to add a null after the space? Wouldn't you rather want to remove the space and end the string there? Seems like a mistake.
Also the code is inefficient, because if you count from the beginning to the end and encounter the first space there, you can stop iterating.
In other words, this code is just awful. You should replace it with something like this:
char* ptr = strchr(string, ' ');
if(ptr != NULL)
{
*ptr = '\0';
}

Incorrect string comparison

I have a problem i cannot figure out at all!
in my program the user enters numbers to be sorted. i had to be able to sort infinity, negative infinity and the so called "Nullity" (these i defined early in the program)
if the user wants to enter infinity for example they have to enter "Pinf" into the string.
my issue is i store the users input in a std::string and then check if the string is "pinf" or "Pinf" even tho i have entered the number 3 so the string is "3", it still goes into the if statement, what have i done wrong?!
My code is below;
string Temp;
cin>> Temp;
if (Temp.find("Pinf")||Temp.find("pinf")) {
Num = Pinfinity;
}
It thinks the if statement is true everytime.
1.Error - you are using | instead of ||.
2.Error - findreturns
The position of the first character of the first match. If no matches
were found, the function returns string::npos.
You should change
if (Temp.find("Pinf")|Temp.find("pinf")) {
to
if ((Temp.find("Pinf") != string::npos) || (Temp.find("pinf") != string::npos)) {
If you are just searching for Pinf or pinf then you can use this. Note the logical or operator is ||.
if (Temp == "Pinf" || Temp == "pinf") {
| is a bitwise or operator. Use || in place of |
if ( Temp.find("Pinf") != npos || Temp.find("pinf") != npos )