Во многих приложениях найдите, означает, "находят на текущей странице/экране", в то время как поиск означает "поиск вся база данных/Интернет". Веб-браузеры, справка онлайн и другие приложения, кажется, делают это различие.
У большинства компиляторов есть свой собственный спецификатор для аргументов size_t
и ptrdiff_t
, Visual C ++, например, использует% Iu и% Id соответственно, я думаю, что gcc позволит вам использовать% zu и% zd.
Вы можете создать макрос:
#if defined(_MSC_VER) || defined(__MINGW32__) //__MINGW32__ should goes before __GNUC__
#define JL_SIZE_T_SPECIFIER "%Iu"
#define JL_SSIZE_T_SPECIFIER "%Id"
#define JL_PTRDIFF_T_SPECIFIER "%Id"
#elif defined(__GNUC__)
#define JL_SIZE_T_SPECIFIER "%zu"
#define JL_SSIZE_T_SPECIFIER "%zd"
#define JL_PTRDIFF_T_SPECIFIER "%zd"
#else
// TODO figure out which to use.
#if NUMBITS == 32
#define JL_SIZE_T_SPECIFIER something_unsigned
#define JL_SSIZE_T_SPECIFIER something_signed
#define JL_PTRDIFF_T_SPECIFIER something_signed
#else
#define JL_SIZE_T_SPECIFIER something_bigger_unsigned
#define JL_SSIZE_T_SPECIFIER something_bigger_signed
#define JL_PTRDIFF_T_SPECIFIER something-bigger_signed
#endif
#endif
Использование:
size_t a;
printf(JL_SIZE_T_SPECIFIER, a);
printf("The size of a is " JL_SIZE_T_SPECIFIER " bytes", a);
Эффективный тип, лежащий в основе size_t, зависит от реализации . Стандарт C определяет его как тип, возвращаемый оператором sizeof; помимо беззнакового и своего рода интегрального типа, size_t может быть практически любым, размер которого может вместить наибольшее значение, которое, как ожидается, будет возвращено функцией sizeof ().
Следовательно, строка формата, которая будет использоваться для size_t, может варьироваться в зависимости от на сервере. Он всегда должен иметь "u", но может быть l или d или, может быть, что-то еще ...
Уловка может состоять в том, чтобы преобразовать его в самый большой интегральный тип на машине, гарантируя отсутствие потерь при преобразовании, а затем с использованием строки формата, связанной с этим известным типом.
Поскольку вы используете C ++, почему бы не использовать IOStreams? Это должно компилироваться без предупреждений и делать правильные вещи с учетом типов, если вы не используете безумную реализацию C ++, которая не определяет оператор <<
для size_t
.
Когда фактический вывод должен выполняться с помощью printf ()
, вы все равно можете комбинировать его с IOStreams, чтобы получить безопасное поведение типов:
size_t foo = bar;
ostringstream os;
os << foo;
printf("%s", os.str().c_str());
Это не суперэффективно, но ваш случай выше относится к файловому вводу-выводу, так что это ваше узкое место, а не код форматирования строки.
вот возможное решение, но оно не совсем красивое ..
template< class T >
struct GetPrintfID
{
static const char* id;
};
template< class T >
const char* GetPrintfID< T >::id = "%u";
template<>
struct GetPrintfID< unsigned long long > //or whatever the 64bit unsigned is called..
{
static const char* id;
};
const char* GetPrintfID< unsigned long long >::id = "%lu";
//should be repeated for any type size_t can ever have
printf( GetPrintfID< size_t >::id, sizeof( x ) );
Спецификатор формата printf
% zu
будет нормально работать в системах C ++; нет необходимости усложнять его.