Estou tentando imprimir tipos como off_t
e size_t
. Qual é o espaço reservado correto para printf()
isso é portátil ?
Ou existe uma maneira completamente diferente de imprimir essas variáveis?
c
portability
format-specifiers
Georg Schölly
fonte
fonte
fopen
,fseek
etc. no Mac OS X.off_t
é utilizado para o deslocamento.Respostas:
Você pode usar
z
para size_t et
ptrdiff_t como emMas minha página de manual diz que algumas bibliotecas mais antigas usavam um caractere diferente
z
e desencorajam o uso dele. No entanto, é padronizado (pelo padrão C99). Para aquelesintmax_t
eint8_t
destdint.h
e assim por diante, existem macros que você pode usar, como outra resposta disse:Eles estão listados na página de manual
inttypes.h
.Pessoalmente, eu apenas converteria os valores
unsigned long
oulong
gostaria que outra resposta recomendasse. Se você usa o C99, pode (e deve) transmitir paraunsigned long long
oulong long
usar os formatos%llu
ou%lld
, respectivamente.fonte
%zd
com asize_t
é um comportamento indefinido devido à incompatibilidade de assinatura (C99 7.19.6.1 # 9). Deve ser%zu
.%zd
com umsize_t
comportamento indefinido, é obtido desse parágrafo ou de qualquer outro. De fato, a definição de%z
# 7 permite explicitamente%d
comsize_t
e 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
:Para imprimir
size_t
:Para imprimir
ssize_t
: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 long
e a sua biblioteca padrão suportar%lld
, você pode esperar com confiança que isso servirá no lugar deintmax_t
. Mas, se isso não acontecer, você precisará recorrerlong
, o que falharia em algumas outras implementações porque é muito pequeno.fonte
ssize_t
tenha o mesmo tamanho quesize_t
, portanto, um código verdadeiramente portátil deve convertê-lointmax_t
e imprimir com o%jd
mesmo valoroff_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.
fonte
off_t
é sempre olong
que tornaria 32 bits (até o Windows de 64 bits usa 32 bits paralong
).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.fonte
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?
fonte
off_t
tipo é 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 printf
Linux, OS X e OpenBSD, todos mostram suporte%z
parasize_t
e%t
paraptrdiff_t
(para C99), mas nenhum deles mencionaoff_t
. Sugestões em geral geralmente oferecem a%u
conversão paraoff_t
, que é "correta o suficiente", tanto quanto eu sei (ambasunsigned int
eoff_t
variam de forma idêntica entre os sistemas de 64 e 32 bits).fonte
unsigned int
e 64 bitsoff_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
z
ouj
sinalizadores 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 comprimentosize_t
na sua plataforma e selecione um deles:E sugiro usar
stdint
tipos em vez de tipos de dados brutos para garantir a consistência.fonte
%zu
pode ser usado para imprimirsize_t
valores. Definitivamente, não se deve recorrer ao uso de um especificadoruint32_t
/uint64_t
format para imprimir umsize_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
.fonte
long long
não existe no padrão C ++ e, portanto, é inerentemente não portátil.use "% zo" para off_t. (octal) ou "% zu" para decimal.
fonte