代码之家  ›  专栏  ›  技术社区  ›  Nick

防止字符串化输出中出现空格

  •  2
  • Nick  · 技术社区  · 5 年前

    我有一个C预处理器宏

    #define QUOTE(...) #__VA_ARGS__
    

    如果我使用它对JSON进行如下字符串化:

    QUOTE(
    {
        "a":1,
        "b":2
    }
    )
    

    输出是

    "{ \"a\":1, \"b\":2 }"
    

    "{\"a\":1,\"b\":2}"
    

    如果没有,更大的问题是我正在为JSON解析编写测试用例,我想让JSON在测试用例中可读,但压缩时不使用空格。测试解析后,我测试从解析结果生成JSON输出,并希望与原始字符串进行比较,但生成的JSON不包含空格。也许除了使用宏之外还有其他的解决方案。。。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Nick    5 年前

    由于我的JSON值不包含空格,到目前为止,我最好的解决方案是在创建字符串后删除空格:

    #define QUOTE(...) #__VA_ARGS__
    
    size_t stripSpaces(char *orig, size_t length) {
        for (size_t i = 0; i < length; i++) {
            if(orig[i] != ' ') { continue; }
            memmove(&orig[i], &orig[i+1], length - i - 2);
            i--;
            length--;
        }
        return length;
    }
    
    void unitTest() {
        char json[] = QUOTE(
            {
                "messageType":176,
                "channel":1,
                "controller":67,
                "ccValue":127
            }
        );
    
        size_t jsonLength = stripSpaces(json, sizeof(json));
    }
    

    bool compareJSON(const char * string1, size_t string1Size, const char * string2, size_t string2Size) {
        bool inQuotes = false;
        for (size_t string1Pos = 0, string2Pos = 0; string1Pos < string1Size && string2Pos < string2Size; ++string1Pos, ++string2Pos) {
            if(!inQuotes) {
                // skip spaces
                while(string1[string1Pos] == ' ' && string1Pos < string1Size) { string1Pos++; }
                while(string2[string2Pos] == ' ' && string2Pos < string2Size) { string2Pos++; }
                // check if we have reached the end of either
                if(string1Pos == string1Size || string2Pos == string2Size) {
                    // if both at the end, equal strings, otherwise not equal
                    return string1Pos == string1Size && string2Pos == string2Size;
                }
            }
            // compare character
            if(string1[string1Pos] != string2[string2Pos]) {
                return false;
            }
            if(string1[string1Pos] == '\"') {
                inQuotes = !inQuotes;
            }
        }
        return true;
    }