Запретить пробелы в строковом выводе - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть макрос препроцессора C

#define QUOTE(...) #__VA_ARGS__

Если я использую его для строкового преобразования JSON следующим образом:

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

Вывод

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

IsЕсть ли способ убрать пробелы?Т.е.

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

Если нет, то более широкой проблемой является то, что я пишу тестовые случаи для анализа JSON, и я хочу сделать JSON читаемым в тестовых случаях, но сгущаться без пробелов.После тестирования синтаксического анализа я тестирую генерирование вывода JSON из проанализированного результата и хочу сравнить с исходной строкой, но сгенерированный JSON не содержит пробелов.Возможно, есть и другие решения, кроме использования макроса ...

1 Ответ

0 голосов
/ 07 февраля 2019

Поскольку мои значения 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;
}
...