2011-01-27 81 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>