2013-05-13 99 views
2

这是我的代码,用于查找用户在给定字符串中输入的子字符串。在字符串中查找子字符串

bool find_str(char *str, char const *substr) { 
    while(*str) { 
     if(*str++ == *substr) { 
      char const *a = substr; 
      while((*str++ == *++a)); /*empty*/ 
      if(*a == '\0') 
       return true; 
     } 
    } 
    return false; 
} 
// If match found, then return true, else false 

int main(void) { 
    printf("%d", find_str("ABCDEF", "CDE")); /* Return true in this case */ 
    printf("%d", find_str("ABCDE", "CDE")); /* Return false in this case */ 

} 

正如注释中所述,只要以附加字符结尾,就会返回true。如果不是,则返回false。我认为增量/减量运算符存在问题。但我怎么找不到?

+1

* str ++,* ++ a,让我想到了试图记住运算符优先级的难题。我不喜欢记忆的事情。请注释它或添加一些括号()。 – John3136 2013-05-13 02:06:20

+0

在这里它是如何工作的,首先它比较A和C,然后用B和C直到C == C,所以在嵌套的同时它会增加一个副作用使得D == D和E == E。(* + +第一个指向D,而* str ++也指向D,但在之后递增) – 2013-05-13 02:07:38

+2

这不是代码评论网站。无论如何,'strstr'这样做 - 10秒google-foo,你可以找到实现,例如http://www.opensource.apple.com/source/xnu/xnu-792.13.8/libsa/strstr.c。在你的代码中,有一些错误:为了学习找到它们,我建议把类似'printf('''%s'=?='%s'\ n“,str,a)比较...你很快就会看到你真正的比较和意识到什么是错误的,然后你可以推理和试验来解决它。提示:正如苹果所做的那样,保持这种“匹配”的逻辑与“随处查看”分开:“strncmp”。 – 2013-05-13 02:17:16

回答

4

这是因为你的代码决定停止在寻找\0只有后执行比较

*str++ == *++a 

这种情况将是true即使在比赛发生在对空终止字符串的结束,所以while循环将愉快地继续超过两个字符串通过空终止符,结果导致未定义的行为。

更改状态退出时*a为零应该解决的问题:

while((*str++ == *++a) && (*a)); 
+0

感谢您的调试,它非常简单 – 2013-05-13 02:11:04

+0

@ ashish2expert:作为旁白(并且由@​​ John3136评论提示),我认为稍微改变会让大多数程序员更容易阅读:'char const * a = substr + 1; while(* a &&(* str ++ == * a ++)){};' – 2013-05-13 02:57:01

1

我分析你的代码一点点,根据我的分析, 我认为这个问题是在这里

 while((*str++ == *++a)); /*empty*/ 

也许你想添加另一份声明中像下面

while((*str++ == *++a) && (*a != '\0')) ; /*empty*/ 

我猜你缺少一个空检查,如果两个指针指向什么空终止他们仍然会向前走这正是发生了什么

我要通过你的代码,并发现了不少有趣的事情

  1. 比方说分配给CDE存储器是在X
  2. 说再次分配用于ABCDEF存储器是在X + 4(这是在我的机器的情况下)
  3. 说分配用于ABCDE存储器块是在一些X + Y或有什么

现在当函数被第二次调用时 指针a和str指针都指向从X + 2开始的各个存储单元,其中字符C满足上述条件,但是即使条件达到了终点,条件仍然是true即在X + 3,因此A会向前移动并指向A,这会使您的程序错误地行为