简体   繁体   中英

C++ strange function behavior

I've been working in C++ a bit lately and only using a small subset of the language (I'd call it C with classes) so I've been messing around trying to learn about some of the other features of the language. To this end I was going to write a simple JSON parser, and almost immediately hit a road block I cannot decipher. Here's the code:

//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;
    }
}

And here's 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;
}

I'm just trying to check if a char is a valid whitespace or a valid control character in 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.

I've been staring for awhile now. I don't even know what search term to put into Google to describe this error (or feature?)... any explanations would be greatly appreciated.

If you read the requirements on strchr

 const char* strchr( const char* str, int ch ); 

str - pointer to the null-terminated byte string to be analyzed

Whereas you are passing in:

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

Neither of those is a null-terminated byte string. You could manually add a 0:

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

Or, better yet, not actually rely on that behavior:

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); }

In 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM