C ++奇怪的函数行为

时间:2015-09-10 22:40:15

标签: c++

我最近一直在C ++工作,只使用了一小部分语言(我把它称为C类)所以我一直在努力学习一些该语言的其他功能。为此,我打算编写一个简单的JSON解析器,几乎立即遇到了一个我无法破译的路障。这是代码:

//json.hpp
#include <cstring>


namespace JSON
{
    const char WS[] = {0x20,0x09,0x0A,0x0D};
    const char CONTROL[] = {0x5B,0x7B,0x5D,0x7D,0x3A,0x2C};

    bool is_whitespace(char c) {
        if (strchr(WS, c) != nullptr)
            return true;
        return false;
    }

    bool is_control_char(char c) {
        if (strchr(CONTROL, c) != nullptr)
            return true;
        return false;
    }
}

这里是main.cpp:

#include <iostream>
#include "json.hpp"

using namespace std;

int main(int argc, char **argv) {
    for(int i=0; i < 127; i++) {
        if(JSON::is_whitespace((char) i)) {
            cout << (char) i << " is whitespace." << endl;
        }
        if(JSON::is_control_char((char) i)) {
            cout << (char) i << " is a control char." << endl;
        }
    }
    return 0;
}

我只是想检查一下char是JSON中的有效空格还是有效的控制字符。

 is whitespace.
 is a control char.
     is whitespace.

 is whitespace.
 is whitespace.
  is whitespace.
, is whitespace.
, is a control char.
: is whitespace.
: is a control char.
[ is whitespace.
[ is a control char.
] is whitespace.
] is a control char.
{ is whitespace.
{ is a control char.
} is whitespace.
} is a control char.

我现在已经盯着看了一会儿。我甚至不知道用什么搜索字词来描述这个错误(或功能?)......任何解释都会非常感激。

1 个答案:

答案 0 :(得分:11)

如果您阅读了strchr

的要求
const char* strchr( const char* str, int ch );
     

str - 指向要分析的以null结尾的字节字符串的指针

你传入的是:

const char WS[] = {0x20,0x09,0x0A,0x0D};
const char CONTROL[] = {0x5B,0x7B,0x5D,0x7D,0x3A,0x2C};

这些都不是以空字符结尾的字节字符串。你可以手动添加0:

const char WS[] = {0x20,0x09,0x0A,0x0D, 0x0};
const char CONTROL[] = {0x5B,0x7B,0x5D,0x7D,0x3A,0x2C, 0x0};

或者,更好的是,实际上并不依赖于这种行为:

template <size_t N>
bool contains(const char (&arr)[N], char c) {
    return std::find(arr, arr+N, c) != (arr+N);
}

bool is_whitespace(char c) { return contains(WS, c); }
bool is_control_char(char c) { return contains(CONTROL, c); }

在C ++ 11中:

template <size_t N>
bool contains(const char (&arr)[N], char c) {
    return std::find(std::begin(arr), std::end(arr), c) !=
        std::end(arr);
}