Comparison between pointer and integer in string class - C++ - 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.

Related

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.

Error: The operator || is undefined for the argument type(s) boolean, char

I keep getting this error message when I want to check the value of a char in a char array.
if(word[0] == 'A'||'E')
Any help would be appreciated.
Here's what you want:
if ( word[0] == 'A' || word[0] == 'E' )
You can't use a Boolean 'OR' with two character operands, which is what your code is attempting. Instead, you need to apply it to two Boolean expressions, as I've done. Hope that helps!

strcmp always true

Why is the if statment always true?
char dot[] = ".";
char twoDots[] = "..";
cout << "d_name is " << ent->d_name << endl;
if(strcmp(ent->d_name, dot) || strcmp(ent->d_name, twoDots))
Am I using strcmp wrong?
strcmp() returns 0 when strings equal and a string cannot be both "." and "..". meaning one side of the || will always be non-zero and therefore the condition is always true.
To correct:
if(0 == strcmp(ent->d_name, dot) || 0 == strcmp(ent->d_name, twoDots))
An alternative would be to use std::string to store the dot variables and use ==:
#include <string>
const std::string dot(".");
const std::string twoDots("..");
if (ent->d_name == dot || ent->d_name == twoDots)
strcmp() returns nonzero in case of a difference (and thus evaluates to true).
Also have a look at the docs (links below). Also have a look on std::string which provides an operator==() for tasks like this. See this answer for the how.
Returns an integral value indicating the relationship between the strings:
A zero value indicates that both strings are equal.
A value greater than zero indicates that the first character that does not match has a greater value in str1 than in str2; And a value less than zero indicates the opposite.
http://www.cplusplus.com/reference/clibrary/cstring/strcmp/
The return value for each of these functions indicates the lexicographic relation of string1 to string2.
Value Relationship of string1 to string2
< 0 string1 less than string2
0 string1 identical to string2
> 0 string1 greater than string2
http://msdn.microsoft.com/en-us/library/e0z9k731%28v=vs.80%29.aspx
strcmp returns -1, 0, or 1 if the strings are lexicographically prior, equal, or later respectively.
To check whether strings are equal, use strcmp(s1, s2) == 0.
Because strcmp returns 0 when equal and 1 or -1 when different, at least one of the two strcmp is returning 1 or -1, the || will return true when any condition is something different of 0, you should do this...
if(strcmp(ent->d_name, dot) == 0 || strcmp(ent->d_name, twoDots) == 0)
I added == 0 after every strcmp
strcmp by itself does not return a boolean. Instead, it returns an int. 0 if match, other if no match. So this should help:
if(0 == strcmp(d_name, dot) || 0 == strcmp(d_name, twoDots)) {
// Other code here
}

Converting char letters to numbers in C++?

I thought I would try and write some encryption program that converts input to numbers in a file.
I made a table, giving each letter its own number. The code itself went a little like this for each letter:
if (Letter = "P")
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
It came up with "cannot convert from 'const char [2]' to 'char'"
Can anyone suggest how I would go about actually getting a number from a letter?
If Letter is a char, use a char literal:
if (Letter == 'P')
...
Your conditional checking is wrong. It should be ==, not =. A single = means assignment whereas a == means conditional checking.
I am assuming Letter is a character array. In that case, you can use strcmp to compare it with P.
if(strcmp(Letter, "P") == 0)
{
// rest of the code
}
Take a look at the strcmp function reference here, if necessary.
If Letter is simply a char, then you need to compare it with P like this -
if(Letter == 'P')
{
// rest of the code
}
A single quote around a character makes it a character literal, which then can be compared against another character using ==.
You can not compare C++ char to C++ string! You should use single quote for chars, not double quotes. Also, the C++ equals operator is not =, it is ==. the single = is the assignment operator.
You should write the condition like this :
if (Letter == 'P')
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
(Letter = "P")
This is an assignment, not comparison.
You probably meant (Letter == "P") which would also be wrong, you need strcmp.
you need to use strcmp to compare....as = is an assignment operator....
I would recommend that when you give us an error message as you did, you give us the full message - including line numbers so that we know where the error occurred (or tell us what line it occurred at). Paying attention to those line numbers can greatly help finding the true problem.
Given the error message I'm assuming Letter is of type char - you need to understand the difference between literal strings (enclosed in double quotes) and literal characters (enclosed in single quotes).
As Luchian also mentioned, you have an assignment rather than an equality test - unlike Visual Basic, if that is where you're coming from, the two have different symbols.
That should thus be:
if (Letter == 'P')

C++: Pointer assignment warning on strchr()

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) == ' '))