2011-01-27 83 views
1

虽然编写了非常简单的程序来清除空白,制表符,换行符,但遇到了一些我实际上并未首先捕获的东西;即使如果条件为真,只有当选项卡,空格或换行不存在,但它仍然与所提到的由于某种原因,执行..这里是代码C歧义问题

 
#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(); 
} 
+2

这`=`和``||是一个标准的逻辑问题。你应该在纸上写下几个案例,并慢慢仔细地评估它们。 – 2011-01-27 20:14:31

+3

这不是有效的C,只是很差的C++。这是什么? – GManNickG 2011-01-27 20:38:16

+0

@GMan:毕竟它应该是C ...... – Christoph 2011-01-27 21:30:25

回答

6

的问题是,

  if(s[i]!=' ' || s[i]!='\t' || s[i]!='\n') 

始终是真实的。如果s[i]是空格,则后面的两个检查是正确的。如果它不是空间,他们的第一个检查是真实的。

为了解决这个问题,这些ORS更改为ANDS:

if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n') 

,或者甚至更好,使用isspace

if(isspace(s[i]) 
9

s[i]!=' ' || s[i]!='\t' || s[i]!='\n'总是真。角色不能等于空格,制表符和换行符。

2

s[i] != x || s[i] != y对于xy的所有不同值都是正确的。您可能想要&&

0

尝试改变

if(s[i]!=' ' || s[i]!='\t' || s[i]!='\n') 

break; 

if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n') 
    break; 
2

如果你想想看,像下面的表达式是犯罪嫌疑人...

a != x || a != y 

无论a是,它永远不会是一个事物或不另一个。所以这总是如此。与and等效错误是总是假的,而不是总是正确的,它看起来像:

a == x && a == y 

这是一个比较容易看到的,对不对?东西a不可能同时是xy。而事实上,这些陈述是由De Morgan's laws.

更新相关:所以,通常你想要的是a != x && a != y。对于第二种情况:a == x || a == y

0

正如其他人已经指出的,你的布尔表达式是一个重言式(即总是为真)。您可能还需要使用的功能strpbrk()而不是重复由标准库提供的功能:

#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…>头时,你应该前缀标识符与std::或添加using指令。或者,也可以使用<….h>。 使用不是从C标准库继承功能,更地道的C++代码是这样的:
 
#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>