Pergunta

Eu estou tentando imprimir tipos como off_t e size_t. Qual é o espaço reservado correto para printf() que é portátil ?

Ou há uma maneira completamente diferente para imprimir essas variáveis?

Foi útil?

Solução

Você pode usar z para size_t e t para ptrdiff_t como em

printf("%zu %td", size, ptrdiff);

Mas a minha manpage diz alguma biblioteca mais antiga usada um personagem diferente do que z e desencoraja uso dele. No entanto, é padronizado (pelo padrão C99). Para aqueles intmax_t e int8_t de stdint.h e assim por diante, existem macros que você pode usar, como uma outra resposta, disse:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

Eles estão listados na página de manual de inttypes.h.

Pessoalmente, gostaria apenas de converter os valores para unsigned long ou long como outra resposta recomenda. Se você usar o C99, em seguida, você pode (e deve, é claro) elenco para unsigned long long ou long long e usar os formatos %llu ou %lld respectivamente.

Outras dicas

Para imprimir off_t:

printf("%jd\n", (intmax_t)x);

Para imprimir size_t:

printf("%zu\n", x);

Para imprimir ssize_t:

printf("%zd\n", x);

Veja 7.19.6.1/7 no padrão C99, ou a documentação POSIX mais conveniente de códigos de formatação:

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

Se a sua aplicação não suporta os códigos de formatação (por exemplo, porque você está no C89), então você tem um pouco de um problema, já que AFAIK não há inteiro tipos de C89 que possuem códigos de formatação e são garantidos para ser tão grande como estes tipos. Então você precisa fazer aplicação específica alguma coisa.

Por exemplo, se o seu compilador tem long long e seus suportes da biblioteca padrão %lld, você pode esperar confiantemente que irá servir no lugar de intmax_t. Mas se isso não acontecer, você vai ter que cair de volta para long, que iria falhar em algumas outras implementações porque é muito pequeno.

Para a Microsoft, a resposta é diferente. VS2013 é em grande parte C99 compatível mas "[o] hh, J, Z, e o comprimento prefixos t não são suportados". para size_t "Isto é, __int32 sem sinal em plataformas de 32-bit, __int64 sem sinal em plataformas de 64-bit" prefixo uso I (olho de capital) com tipo especificador o, u, X, ou X. Veja VS2013 Tamanho especificação

Como para off_t, ele é definido como muito tempo na VC \ include \ sys \ types.h.

Qual versão do C você está usando?

Em C90, a prática padrão é fundido ao sinal ou sem sinal de longo, conforme apropriado, e imprimir em conformidade. Eu vi% z para size_t, mas Harbison e Steele não mencioná-lo sob printf (), e em qualquer caso, que não iria ajudá-lo com ptrdiff_t ou o que quer.

Em C99, os vários tipos _T vêm com seus próprios macros printf, então algo como "Size is " FOO " bytes." eu não sei detalhes, mas isso é parte de uma bastante grande formato numérico incluem arquivo.

Você vai querer usar as macros de formatação de inttypes.h.

Veja esta pergunta: Cruz seqüência de formato de plataforma para as variáveis ??de tipo size_t?

Olhando para man 3 printf no Linux, OS X, e OpenBSD tudo show suporte para %z para size_t e %t para ptrdiff_t (para C99), mas nenhum deles menção off_t. Sugestões na natureza geralmente oferecem-se a conversão %u para off_t, que é "bastante correta", tanto quanto eu posso dizer (ambos unsigned int e off_t variar de forma idêntica entre sistemas de 64 bits e 32 bits).

Eu vi esse post pelo menos duas vezes, porque a resposta aceita é difícil lembrar-se é para mim (eu raramente uso z ou j bandeiras e são parece não plataforma independente ).

O padrão nunca diz claramente o comprimento de dados exacto de size_t, então eu sugiro que você deve primeiro verificar a size_t comprimento em sua plataforma, em seguida, selecionar um deles:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

E eu sugiro usar tipos stdint em vez de tipos de dados brutos para consistência.

Se bem me lembro, a única maneira portátil para fazê-lo, é converter o resultado para "long int não assinado" e uso %lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

uso "% zo" para off_t. (Octal) ou "% zu" para decimal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top