Is this piece of code any good to check if a pointer or variable hold a nullptr value?
if(strcmp(variable/pointer, nullptr) == 0){
Do something cool
}
I'm trying to work on some code and I want to know the best way to check if there is a nullptr value present.
Thanks.
I think what you want is
if (!pointer || !variable) {
// do something cool
}
!pointer is essentially the same thing as pointer == nullptr and is considered by some to be better style. See Can I use if (pointer) instead of if (pointer != NULL)?
strcmp is meant to be for C string comparisons. https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm
You cannot use strcmp to check whether a variable is equal to nullptr. From strcmp documentation:
Parameters
lhs, rhs - pointers to the null-terminated byte strings to compare
Not only do the input arguments to strcmp need to point to byte strings, they must point to null-terminated byte strings.
Besides, you are making things may more complex than they need to be. You can just use:
if ( variable != nullptr )
{
// Do something
}
else
{
// Do something else
}
strcmp() has undefined behaviour if either argument is a null pointer. Therefore it is necessary to check for null before calling strcmp().
For example, to only call strcmp() if both intended arguments are not null
if (first && second && !strcmp(first, second))
{
// first and second are both non-null, and contain matching strings
}
or (more verbosely, C++11 and later)
if (first != nullptr && second != nullptr && strcmp(first, second) == 0)
{
// first and second are both non-null, and contain matching strings
}
In C++, you'd be better off using the std::string type, rather than messing around with arrays of char, string termination, and functions like strcmp().
Related
I am creating a server/client socket program and am in the process of making a method to print server input.
Here's my code:
void *admin_handler (void *ptr) {
char strBuf [100000];
const char strExit [20] = "Server: terminated.";
while(1) {
scanf ("%s", strBuf);
int i;
for (i=0; i < nClient; i++){
if (strBuf == "Exit"){
write (nFDList [i], strExit, strlen (strExit) + 1);
}
else {
write (nFDList [i], strBuf, strlen (strBuf) + 1);
}
}
};
}
When I execute, though, even when I type in "Exit", it still executes the else statement. How can I modify the if statement to execute when I type "Exit"?
The best way to compare strings in C is using strcmp() (or strncmp() if one is interested in safety with unknown strings).
The equality operator == compares the operands directly, after they "decay" to pointers; the pointers do not change and are of course different. strcmp(), by contrast, inspects the contents of the memory pointed to, which may be equal.
As an aside, the same issue exists in Java: == checks whether both sides are the same objects, similar to the C equivalent, while .equals() inspects the object contents, similar to strcmp().
C#, by contrast, overloaded == for strings so that it would indeed look at the contents, which makes a lot of sense for a language where operator overloading is possible (which C is not): Testing the identity of the objects is almost never desired and, as we see, is a common source of error.
Hey so recently I tried getting a C++ program of mine to take in a parameter "-f" (it helps create a file of data that the user can enter), and so I tried the typical if statement:
if (argv[1] == "-f") { cout << "Please input a file name:" << endl;}
But unfortunately, it doesn't seem to work. The code is registering that "-f" is an argument to add to argc, it just doesn't want to check that it's properly "-f". I even tried atoi to change "f" to 102 and check it via an integer, but it just doesn't seem to be working. Thank you for your time!
argv[1] == "-f" is a pointer comparison. It will never be true because a command line argument will never have the same address as a string literal in your program.
Try if (strcmp(argv[1], "-f") == 0) instead.
Both argv[something] and -f are C-style strings which decay (in most cases) to a pointer to the first character of that string.
Hence a simple comparison, unlike the std::string type, will not work since it will be comparing two distinct pointers. If you want to compare C-style strings, strcmp and its brethren are the way to go.
Otherwise you can turn both those values into actual C++ strings and use the equality operator to compare them.
I'd opt for the former:
if (strcmp (argv[1], "-f") == 0) {
argOneIsMinusF();
}
I have a vector of strings and I want to compare the first element of the vector with a bunch of different "strings".
Here is what i wanted to do:
if (strcmp(myString[0], 'a') == 0)
but strcmp doesnt work. I basically want to check the contents of myString[0] with a bunch of different characters to see if there is a match. So it would be something like
if (strcmp(myString[0], 'a') == 0){
}
else if (strcmp(myString[0], 'ah') == 0){
}
else ifif (strcmp(myString[0], 'xyz') == 0)
etc..
What can i use to do this comparison? Compiler complains about "no suitable conversion from std:string to "constant char*" exists so i know it doesnt like that im doing a string to char comparison, but i cant figure out how to correctly do this.
std::string overloads operator== to do a string comparison, so the equivalent to
if (strcmp(cString, "other string") == 0)
is
if (cppString == "other string")
So your code becomes (for example)
else if (myString[0] == "ah")
'a' is not a string, it is a character constant. You need to use "a", "ah", "xyz", etc.
Also, if you want to use strcmp, you need to use:
if (strcmp(myString[0].c_str(), "a") == 0)
You can also use the overloaded operator== to compare a std::string with a char const*.
if (myString[0] == "a")
You have marked this post as C++.
compare the first element of the vector with a bunch of different
"strings".
If I am reading your post correctly, the first element of the vector is a std::string.
std::string has a function and an operator to use for string-to-string comparison.
The function is used like:
if (0 == pfnA.compare(pfnB))
As described in cppreference.com:
The return value from std::string.compare(std::string) is
negative value if *this appears before the character sequence specified by the arguments, in lexicographical order
positive value if *this appears after the character sequence specified by the arguments, in lexicographical order
zero if both character sequences compare equivalent
The operator==() as already described, returns true when the two strings are the same.
struct dic
{
string key;
int code;
};
dic H[71];
Now using key in the condition of the while-statement gives me an error.
while ((H[h].key)!= NULL)
{
}
The error I am getting is:
error: no match for 'operator!=' in 'H[h].dic::key != 0'
the type of dic::key is string, and you are trying to compare it to an integer (NULL == 0), which is not implemented. You need to check if the string is empty:
while (!H[h].key.empty()) {
...
}
The key of the element is a string. You can not compare a string to NULL as it is an object not a pointer. The macro NULL will most probably either defined as a pointer or an int value and neither of those is comparable to string.
The macro NULL is often defined to either 0 or (void *) 0, none of those values can be used when comparing to a std::string (unless, of course, you implement your own custom comparison operator, which you shouldn't).
If you want to check if a string is empty, use std::string::empty.
Maybe you wanted to say:
if (H[h].key.empty()) { ... }
everyone, I have some question about C++, what do You actually prefer to use
int* var = 0;
if(!var)...//1)
or
if(var == 0)..//2)
what are the pros and cons? thanks in advance
I prefer if (!var), because then you cannot accidentally assign to var, and you do not have to pick between 0 and NULL.
I've always been taught to use if (!var), and it seems that all the idiomatic C(++) I've ever read follows this. This has a few nice semantics:
There's no accidental assignment
You're testing the existence of something (ie. if it's NULL). Hence, you can read the statement as "If var does not exist" or "If var is not set"
Maps closely to what you'd idiomatically write if var was a boolean (bools aren't available in C, but people still mimic their use)
Similar to the previous point, it maps closely to predicate function calls, ie. if (!isEmpty(nodeptr)) { .. }
Mostly personal preference. Some will advise that the first is preferred because it becomes impossible to accidentally assign instead of compare. But by that same token, if you make a habit of putting the rvalue on the left of the comparison, the compiler will catch you when you blow it:
if( 0 == var )
...which is certainly true. I simply find if( !var ) to be a little more expressive, and less typing.
They will both evaluate the same, so there's no runtime difference. The most important thing is that you pick one and stick with it. Don't mix one with the other.
Either one is good, though I personally prefer 2 - or something like it.
Makes more sense to me to read:
if ( ptr != NULL )
than
if ( ptr )
The second I may confuse for just being a boolean to look at, but the first I'd be able to tell immediately that it's a pointer.
Either way, I think it's important to pick one and stick with that for consistency, though - rather than having it done in different ways throughout your product.
A few years has passed...
The C++11 standard introduced nullptr to check for null pointers and it should be used as it ensure that the comparison is actually done on a pointer.
So the most robust check would be to do:
if(myPtr != nullptr)
The problem with !var is that it's valid if var is a boolean or a numerical values (int, byte etc...) it will test if they are equal 0 or not.
While if you use nullptr, you are sure that you are checking a pointer not any other type:
For example:
int valA = 0;
int *ptrA = &valA;
if(!valA) // No compile error
if(!*ptrA) // No compile error
if(!ptrA) // No compile error
if(valA != nullptr) // Compile error, valA is not a pointer
if(*ptrA != nullptr) // Compile error, *ptrA is not a pointer
if(ptrA != nullptr) // No compile error
So, it's pretty easy to make a mistake when manipulating pointer to an int as in your example, that's why nullptr should be used.
I would prefer option 3:
if(not var)
{
}
The new (well since 1998) operator keywords for C++ can make code easier to read sometimes.
Strangely enough, they seem to be very unknown. There seem to be more people who know what trigraphs are (thank you IOCCC!), than people who know what operator keywords are. Operator keywords have a similar reason to exist: they allow to program in C++ even if the keyboard does not provide all ANSII characters. But in contradiction to trigraphs, operator keywords make code more readable instead of obfuscating it.
DON'T use NULL, use 0.
Strictly speaking, pointer is not bool, so use '==' and '!=' operators.
NEVER use 'if ( ptr == 0 )', use 'if ( 0 == ptr )' instead.
DON'T use C-pointers, use smart_ptr instead. :-)
According to the High Integrity C++ coding Standard Manual: for comparison between constants and variables you should put the constant on the left side to prevent an assignment instead of an equality comparison, for example:
Avoid:
if(var == 10) {...}
Prefer
if(10 == var) {...}
Particularly in your case I prefer if(0 == var) because it is clear that you are comparing the pointer to be null (0). Because the ! operator can be overloaded then it could have other meanings depending on what your pointer is pointing to: if( !(*var) ) {...}.