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

标签 c c-preprocessor

我有一个 C 预处理器宏

#define QUOTE(...) #__VA_ARGS__

如果我用它像这样对 JSON 进行字符串化:

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

输出是

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

有什么办法可以去除空格吗?即

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

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

最佳答案

由于我的 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));
}

编辑:感谢@Bodo 的建议,我也可以在比较字符串时忽略空格,而不是去除空格。

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

关于c - 防止字符串化输出中出现空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54576361/

相关文章:

c - 打印包的十六进制值

c++ - 从 wglUseFontOutlines 获取积分?

c - 如何进行这个初始化?

c - 无法在不丢失预处理器的情况下在 C 中包含 ASM 头文件

C 开关/案例宏,多个案例

CLion 宏重排

c++ - 如何转换 RGB -> YUV -> RGB(双向)

c - 等价于 Julia 语言中的 C 编程语法 "#define"

c++ - 获取 if 语句以检查定义的宏

c - 替换#defines常量