1

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?

Celeritas
  • 14,489
  • 36
  • 113
  • 194
  • 2
    Look at the return values section: http://www.cplusplus.com/reference/clibrary/cstring/strcmp/ – TheZ Aug 17 '12 at 21:08
  • 2
    Short answer is yes but you may want to use `std::string` in C++ anyway ... – AJG85 Aug 17 '12 at 21:17

5 Answers5

11

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)
hmjd
  • 120,187
  • 20
  • 207
  • 252
7

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.


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
Community
  • 1
  • 1
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • How come `strcmp` works on `std::string` when it expects `char *`? – Celeritas Aug 17 '12 at 21:53
  • 1
    @Celeritas `strcmp` doesn't work on `std::string` (unless you order the corresponding zero-terminated [C-string](http://www.cplusplus.com/reference/string/string/c_str/)). To test for equivalence you'd simply use [`s1 == s2`](http://www.cplusplus.com/reference/string/operators/). – moooeeeep Aug 18 '12 at 11:11
3

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.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
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

saul672
  • 737
  • 5
  • 6
0

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
}
user9311010
  • 79
  • 11