CS50 Pset6 错误 405 继续打印 server.c

CS50 Pset6 error 405 keeps on printing server.c

所以我的代码,无论如何,returns 错误 405(一旦请求行中只有两个空格的测试通过)。这让我相信我在创建代码以确定 "GET" 实际上是第一个词时犯了一个错误。这是导致方法类型为 "GET" 或其任何大写的 "check" 之前的所有代码。

   int s;
   s=0;
   int i=0;
    for(int q=0; q<strlen(line); q++)
    {
        if(line[q] == ' ')
            s++;
    }
    if(s!=2)
    {
       error(400);
       return false;
    }
if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T')||
    (line[i+3] != ' '  ))
        {
            error(405);
            return false;
        }

为什么这总是 return 错误?我已将 int i 初始化为 0

Any reason this would always return false?

原因:

  • if 语句视为:

    if(expression_1 || expression_2 || expression_3 || expression_4)
    //where
    //expression_1 is (line[i] != 'g' || line[i] != 'G')
    //expression_2 is (line[i] != 'e' || line[i] != 'E')
    //expression_3 is (line[i] != 't' || line[i] != 'T')
    //expression_4 is (line[i] != ' ')   
    
  • 让我们将 line 视为 GET

  • 现在,expression_1 总是 评估为 true 即使 line[i] == G 因为 line[i] != 'g'true。因此,(line[i] != 'g' || line[i] != 'G')true,因为 true || false == true

  • 现在不再对进一步的表达式求值,因为 || 是惰性运算符,它会在第一次出现 true 时停止求值,因为 true || anything == true

  • 因此,总是进入if块,总是返回false块。


解法:

  • 更改代码中的 if :

    if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T') || (line[i+3] != ' '  ))
    
  • 以下内容:

    if((line[i] != 'g' && line[i] != 'G') || (line[i+1] != 'e' && line[i+1] != 'E') || (line[i+2] != 't' && line[i+2] != 'T') || (line[i+3] != ' '  ))
    
  • 这里 line[i] != 'g' && line[i] != 'G' 被评估为 false 作为 true && false == false 并且进一步的表达式被检查直到遇到 true

  • 如果没有遇到true那么if()块不会进入

此外,

  • 作为 @twalberg has suggested in the ,如果您将 if 语句作为 if( !strncasecmp(line, "get ", 3) ) 通过包含 strings.h头文件

  • 在这里了解更多关于 strncasemp() 函数的信息:click

这种比较使代码更难阅读。使用函数 strncasecmp()(在 string.hstrings.h 中)代替:

if (strncasecmp(line, "get ", strlen("get ")) != 0) {
    // ...
}

这将修复该行中的逻辑错误——您当前的比较将始终计算 true。我还建议启用更多编译器警告,因为这是任何编译器都应该捕捉到的东西。