Estou tentando imprimir tipos como off_te size_t. Qual é o espaço reservado correto para printf() isso é portátil ?
Ou existe uma maneira completamente diferente de imprimir essas variáveis?
Estou tentando imprimir tipos como off_te size_t. Qual é o espaço reservado correto para printf() isso é portátil ?
Ou existe uma maneira completamente diferente de imprimir essas variáveis?
Respostas:
Você pode usar zpara size_t e tptrdiff_t como em
printf("%zu %td", size, ptrdiff);
Mas minha página de manual diz que algumas bibliotecas mais antigas usavam um caractere diferente ze desencorajam o uso dele. No entanto, é padronizado (pelo padrão C99). Para aqueles intmax_te int8_tde stdint.he assim por diante, existem macros que você pode usar, como outra resposta disse:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Eles estão listados na página de manual inttypes.h.
Pessoalmente, eu apenas converteria os valores unsigned longou longgostaria que outra resposta recomendasse. Se você usa o C99, pode (e deve) transmitir para unsigned long longou long longusar os formatos %lluou %lld, respectivamente.
%zdcom a size_té um comportamento indefinido devido à incompatibilidade de assinatura (C99 7.19.6.1 # 9). Deve ser %zu.
%zdcom um size_tcomportamento indefinido, é obtido desse parágrafo ou de qualquer outro. De fato, a definição de %z# 7 permite explicitamente %dcom size_te o tipo assinado correspondente, e §6.2.5 # 9 permite explicitamente o uso de valores de tipos não assinados onde o tipo assinado correspondente é esperado, desde que o valor seja um valor não negativo válido do tipo assinado.
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);
Consulte 7.19.6.1/7 no padrão C99 ou a documentação mais conveniente do POSIX sobre códigos de formatação:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Se sua implementação não suportar esses códigos de formatação (por exemplo, porque você está no C89), você tem um problema, já que no AFAIK não há tipos de número inteiro no C89 que possuam códigos de formatação e que sejam tão grandes como esses tipos. Então, você precisa fazer algo específico da implementação.
Por exemplo, se o seu compilador tiver long longe a sua biblioteca padrão suportar %lld, você pode esperar com confiança que isso servirá no lugar de intmax_t. Mas, se isso não acontecer, você precisará recorrer long, o que falharia em algumas outras implementações porque é muito pequeno.
ssize_ttenha o mesmo tamanho que size_t, portanto, um código verdadeiramente portátil deve convertê-lo intmax_te imprimir com o %jdmesmo valor off_t.
Para a Microsoft, a resposta é diferente. O VS2013 é amplamente compatível com C99, mas "[h] os prefixos hh, j, z e comprimento não são suportados". Para size_t ", ou seja, __int32 não assinado em plataformas de 32 bits, __int64 não assinado em plataformas de 64 bits" use o prefixo I (maiúscula) com o especificador de tipo o, u, x ou X. Consulte a especificação de tamanho do VS2013
Quanto a off_t, é definido desde que VC \ include \ sys \ types.h.
off_té sempre o longque tornaria 32 bits (até o Windows de 64 bits usa 32 bits para long).
Qual versão do C você está usando?
Em C90, a prática padrão é converter em assinado ou não assinado por muito tempo, conforme apropriado, e imprimir em conformidade. Eu já vi% z para size_t, mas Harbison e Steele não mencionam isso em printf () e, de qualquer forma, isso não ajudaria você com ptrdiff_t ou o que seja.
No C99, os vários tipos _t vêm com suas próprias macros printf, então algo como "Size is " FOO " bytes." eu não sei detalhes, mas isso faz parte de um formato numérico bastante grande que inclui o arquivo.
Você desejará usar as macros de formatação de inttypes.h.
Veja esta pergunta: Cadeia de caracteres de formato de plataforma cruzada para variáveis do tipo size_t?
off_ttipo é maior que um ponteiro em qualquer sistema de 32 bits que suporte arquivos grandes (que é a maioria dos sistemas de 32 bits atualmente).
Olhando para man 3 printfLinux, OS X e OpenBSD, todos mostram suporte %zpara size_te %tpara ptrdiff_t(para C99), mas nenhum deles menciona off_t. Sugestões em geral geralmente oferecem a %uconversão para off_t, que é "correta o suficiente", tanto quanto eu sei (ambas unsigned inte off_tvariam de forma idêntica entre os sistemas de 64 e 32 bits).
unsigned inte 64 bits off_t. Portanto, o elenco causaria a perda de dados.
Vi este post pelo menos duas vezes, porque a resposta aceita é difícil de lembrar para mim (raramente uso zou jsinalizadores e eles parecem não ser independentes da plataforma ).
O padrão nunca indica claramente o tamanho exato dos dados size_t, por isso sugiro que você verifique primeiro o comprimento size_tna sua plataforma e selecione um deles:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
E sugiro usar stdinttipos em vez de tipos de dados brutos para garantir a consistência.
%zupode ser usado para imprimir size_tvalores. Definitivamente, não se deve recorrer ao uso de um especificador uint32_t/ uint64_tformat para imprimir um size_t, pois não há garantia de que esses tipos sejam compatíveis.
Pelo que me lembro, a única maneira portátil de fazê-lo, é converter o resultado em "int longo não assinado" e usá-lo %lu.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long longnão existe no padrão C ++ e, portanto, é inerentemente não portátil.
fopen,fseeketc. no Mac OS X.off_té utilizado para o deslocamento.