Строка кросс-платформенного формата для переменных типа size_t?

Мне нравится метод Тиммерца с небольшим завихрением лимона. Если вы когда-либо возвращаете contentType text / html, когда ожидаете JSON, вы, скорее всего, будете перенаправлены. В моем случае я просто перезагружаю страницу и перенаправляется на страницу входа. О, и проверьте, что состояние jqXHR равно 200, что кажется глупым, потому что вы находитесь в функции ошибки, верно? В противном случае допустимые ошибки приведут к повторной перезагрузке (oops)

$.ajax(
   error:  function (jqXHR, timeout, message) {
    var contentType = jqXHR.getResponseHeader("Content-Type");
    if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
        // assume that our login has expired - reload our current page
        window.location.reload();
    }

});
32
задан chills42 3 November 2008 в 13:14
поделиться

7 ответов

PRIuPTR макрос (от < inttypes.h>) определяет десятичный формат для uintptr_t, который должен всегда быть достаточно большим, который можно бросить size_t к нему без усечения, например,

fprintf(stream, "Your size_t var has value %" PRIuPTR ".", (uintptr_t) your_var);
20
ответ дан 27 November 2019 в 20:57
поделиться

Единственная вещь, о которой я могу думать, типичное:

#ifdef __WIN32__ // or whatever
#define SSIZET_FMT "%ld"
#else
#define SSIZET_FMT "%zd"
#endif

и затем использующий в своих интересах сворачивание констант:

fprintf(stream, "Your size_t var has value " SSIZET_FMT ".", your_var);
8
ответ дан 27 November 2019 в 20:57
поделиться

Dan Saks написал статью в Дизайне Встроенных систем, который покрыл этот вопрос. По словам Dan, %zu является стандартным путем, но немного компиляторов поддерживали это. Как альтернатива, он рекомендовал использовать %lu вместе с явным броском аргумента неподписанному долго:

size_t n;
...
printf("%lu", (unsigned long)n);
4
ответ дан 27 November 2019 в 20:57
поделиться

Используйте boost::format. Это безопасно с точки зрения типов, таким образом, это распечатает size_t правильно с %d, также Вы не должны помнить помещать c_str() на std::string с при использовании его, и даже если Вы передадите число %s или наоборот, то это будет работать.

2
ответ дан 27 November 2019 в 20:57
поделиться

Я не знаю ни о каком удовлетворяющем решении, но Вы могли бы полагать, что специализированная функция отформатировала size_t объекты к строке и распечатала строку.

(С другой стороны, если можно выйти сухим из воды, повышение:: отформатируйте такого рода вещь дескрипторов легко.)

1
ответ дан 27 November 2019 в 20:57
поделиться

Вам просто нужно найти целочисленный тип с самым большим классом хранения, привести к нему значение и затем использовать соответствующую строку формата для большего типа. Обратите внимание, что это решение будет работать для любого типа (ptrdiff_t и т. Д.), А не только для size_t.

Вы хотите использовать uintmax_t и макрос формата PRIuMAX. Для Visual C ++ вам потребуется загрузить c99-совместимые заголовки stdint.h и inttypes.h, поскольку Microsoft их не предоставляет.

Также см.

http://www.embedded.com/columns / Technicalinsights / 204700432

Эта статья исправляет ошибки в статье, цитируемой Фредерико.

1
ответ дан 27 November 2019 в 20:57
поделиться

Здесь действительно есть два вопроса. Первый вопрос - какова правильная строка спецификатора printf для трех платформ. Обратите внимание, что size_t является беззнаковым типом.

В Windows используйте «% Iu ».

В Linux и OSX , используйте «% zu ».

Второй вопрос - как поддерживать несколько платформ, учитывая, что такие вещи, как строки формата, могут отличаться на каждой платформе. Как отмечали другие люди, использование #ifdef быстро становится некрасивым.

Вместо этого напишите отдельный make-файл или файл проекта для каждой целевой платформы. Затем обратитесь к спецификатору по имени макроса в ваших исходных файлах, соответствующим образом определяя макрос в каждом make-файле. В частности, и GCC, и Visual Studio принимают переключатель 'D' для определения макросов в командной строке.

Если ваша система сборки очень сложна (несколько параметров сборки, сгенерированные источники и т. д.), поддержка трех отдельных make-файлов может стать громоздкой и вам придется использовать какую-то продвинутую систему сборки, такую ​​как CMake или автоинструменты GNU. Но основной принцип тот же - используйте систему сборки для определения макросов для конкретной платформы вместо того, чтобы помещать логику определения платформы в исходные файлы.

13
ответ дан 27 November 2019 в 20:57
поделиться