Uint64_t nasıl yazdırılır? Aşağıdakilerle başarısız olur: "biçiminde sahte izleyen '%'"


133

Ben printf uint64_t çok basit bir test kodu yazdım:

#include <inttypes.h>
#include <stdio.h>

int main()
{
  uint64_t ui64 = 90;
  printf("test uint64_t : %" PRIu64 "\n", ui64);
  return 0;
}

Derlemek için Ubuntu 11.10 (64 bit) ve gcc sürüm 4.6.1 kullanıyorum, ancak başarısız oldu:

main.cpp: In function int main()’:
main.cpp:9:30: error: expected ‘)’ before PRIu64
main.cpp:9:47: warning: spurious trailing ‘%’ in format [-Wformat]

1
Görünüşe göre C kodu C ++ olarak derliyorsunuz, bu sizin hatanızdır. Dosyanızı yeniden adlandırır main.cve gcc ile derlerseniz, her şey yolunda gitmelidir.
Jens Gustedt


Gcc veya clang ile, -std=c11kullandığınız standardın sürümünü veya sürümünü belirtmek iyi bir fikirdir . Bu ve diğer hataları yakalar. Ayrıca -Wall -Wextra -Wpedantic -Wconversionen azından tavsiye ederim .
Davislor

Yanıtlar:


164

ISO C99 standardı, bu makroların yalnızca açıkça talep edilmesi durumunda tanımlanması gerektiğini belirtir.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan, sorununuzu çözmüşse cevabı kabul edilmiş olarak işaretlemeyi unutmayın (soldaki onay işareti resmini tıklayın).
zneak

9
Hm, sadece başlık dahil yeterli. __STDC_FORMAT_MACROSMakro yalnızca C ++ eklenmek için gereklidir.
Jens Gustedt

15
@Jens: Gerçekten; __STDC_FORMAT_MACROSyalnızca C99'daki bir dipnotta görünür, bu da C ++ 'ın bu makroları yalnızca isteğin varlığında tanımladığını gösterir. Ancak C ++ komitesi şu öneriyi göz ardı etmeyi seçti: örn. N3242 taslağında, 27.9.2 / 3: Not: <cinttypes> tarafından tanımlanan makrolar koşulsuz olarak sağlanır. Özellikle, C standardının dipnot 182'sinde belirtilen __STDC_FORMAT_MACROS sembolü C ++ 'da rol oynamaz. Derleyiciler yetiştiğinde, __STDC_FORMAT_MACROSC veya C ++ 'da ihtiyacımız olmayacak .
John Marshall

3
@John Marshall g ++ 4.7.3, <inttypes.h> dahil edildiğinde bile makroyu gerektirir.
crockeea

4
@Eric: Görünüşe göre g ++ 4.7.3 yakalanmamıştı! Aslında, muhtemelen bu hata düzeltmesini önleyen bir glibc sürümü ile kullanıyorsunuz . Bu glibc raporunda tartışıldığı gibi, g ++ 4.7.3'ün libstdc ++ cihazınızın bu soruna geçici bir çözüm bulmak için kodu vardır. -std=c++0x<İnttypes.h> yerine #cinttypes> ile derleyebilir ve belki de #include ederseniz, siz tedarik etmeden biçim makrolarını sağlayacağına inanıyorum __STDC_FORMAT_MACROS.
John Marshall

4

Centos 5.xi altında memcached derlerken aynı sorunu var.

Çözüm, en azından gcc ve g ++ 'ı 4.4 sürümüne yükseltmektir.

Derlemeden önce CC / CXX cihazınızın sağ ikili dosyalara ayarlandığından (dışa aktarıldığından) emin olun.


1

C ++ etiketini eklediğinizden , {fmt} kitaplığını kullanabilir ve PRIu64makrodan ve diğer printfsorunlardan tamamen kaçınabilirsiniz :

#include <fmt/core.h>

int main() {
  uint64_t ui64 = 90;
  fmt::print("test uint64_t : {}\n", ui64);
}

Bu kütüphaneye dayalı biçimlendirme olanağı C ++ 20: P0645 standardında standartlaştırma için önerilmiştir .

Feragatname : {fmt} yazarıyım.


Güzel! Benzer bir şey mi geliyor sscanf?
ceztko

Büyük olasılıkla. Değiştirme olasılığını araştırıyoruz scanf.
vitaut

Harika! Ayrıca bir yerel ve / veya yerel seçilebilir sürümüne doğru ilerleme olup olmadığını merak ediyorum std::to_string(). Cppreference sayfası hala sadece bağlantılıdır std::to_chars(), bu gerçekten insanların ihtiyaç duyduğu şey değildir. Acaba fmtve / veya c ++ 20 bununla ilgilenip ilgilenmediğini merak ediyorum .
ceztko

std::to_stringmuhtemelen olduğu gibi kalacaktır, ancak std::formatyerel ayarın kullanılıp kullanılmayacağını denetlemenize olanak tanır (ve varsayılan olarak yerel ayarı kullanmaz).
vitaut
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.