Reputation: 355
While coding very simple program for removing blanks, tabs, newlines I came across something I don't actually catch on first; even though if condition is true only when tab, space or newline doesn't exist it's still executed with the mentioned for some reason.. here is the code
#include <cstdio>#include <cstring>
#include <stdio.h>
#include <string.h>
#define LGT 100
void rem(char s[])
{
int i;
for(i=(strlen(s)-1);i>=0;i--)
if(s[i]!=' ' || s[i]!='\t' || s[i]!='\n')
break;
s[i+1]='\0';
}
int main(void)
{
char v[LGT]={"sdsfg\t"};
rem(v);
printf("%s\n",v);
getchar();
}
Upvotes: 1
Views: 1450
Reputation: 169683
As others already pointed out, your boolean expression is a tautology (ie always true). You might also want to use the function strpbrk()
instead of duplicating functionality provided by the standard library:
#include <stdio.h>
#include <string.h>
// …
char text[] = "foo\tbar\n";
char *tail = strpbrk(text, " \t\n");
if(tail) *tail = 0;
printf("<%s>", text); // prints <foo>
<c…>
headers, you should prefix identifiers with std::
or add a using
directive. Alternatively, use <….h>
instead.
Using functionality not inherited from the C standard library, more idiomatic C++ code would look like this:
#include <iostream> #include <string> // … std::string text = "foo\tbar\n"; std::size_t pos = text.find_first_of(" \t\n"); if(pos != std::string::npos) text.erase(pos); std::cout << '<' << text << '>'; // prints <foo>
Upvotes: 0
Reputation: 146143
If you think about it, any expression like the following is suspect...
a != x || a != y
Whatever a
is, it will always not be one thing OR not be another. So this is always true. The equivalent mistake with and
is always false rather than always true, and it looks like:
a == x && a == y
It's a little easier to see, right? Thing a
can't possibly be both x
AND y
at the same time. And in fact these statements are related by De Morgan's laws.
Update: So, typically what you want is a != x && a != y
. For the second case: a == x || a == y
.
Upvotes: 2
Reputation: 372982
The problem is that
if(s[i]!=' ' || s[i]!='\t' || s[i]!='\n')
Is always true. If s[i]
is a space, then the latter two checks are true. If it's not a space, them the first check is true.
To fix this, change these ors to ands:
if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n')
Or, even better, use isspace
:
if(isspace(s[i])
Upvotes: 6
Reputation: 3915
try changing
if(s[i]!=' ' || s[i]!='\t' || s[i]!='\n')
break;
with
if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n')
break;
Upvotes: 0
Reputation: 89997
s[i] != x || s[i] != y
is true for all different values of x
and y
.
You probably want &&
.
Upvotes: 2
Reputation: 22389
s[i]!=' ' || s[i]!='\t' || s[i]!='\n'
is always true. A character can't be equal to both a space, a tab and a newline.
Upvotes: 9