C ++ cout hex değerleri?


150

Ben yapmak istiyorum:

int a = 255; 
cout << a;

ve çıktıda FF gösteriyor mu, bunu nasıl yaparım?

Yanıtlar:


208

Kullanım:

#include <iostream>

...

std::cout << std::hex << a;

Baştaki sıfırlar ve büyük / küçük harf gibi çıktı numarasının tam biçimlendirmesini kontrol etmek için başka birçok seçenek vardır .


34
Bu, gelecekteki tüm çıktıları cout'tan hex'e değiştiriyor gibi görünüyor; bu nedenle, yalnızca 'a'nın onaltılık olarak yazdırılmasını istiyorsanız, cout << hex << a << dec;onu eski haline getirmek gibi bir şey isteyebilirsiniz .
— ShreevatsaR

16
@ShreevatsaR Dec over hex geri yüklemeyle ilgili bir sorun, dec'in daha önce ayarlanan değer olmaması olabilir, özellikle de genel bir kitaplık yöntemi yazıyorsanız. Bu sorunun , durumun nasıl depolanacağı ve geri yükleneceği ile ilgili bazı yanıtları vardır. Durumu ile kaydedebilir ios::fmtflags f(cout.flags());ve ile geri yükleyebilirsiniz out.flags(f);.
— jtpereyda

Sonra tarafından restorestd::cout.flags(f);
— eigenfield

44

std::hex<ios>hangisinin dahil edildiği tanımlanır <iostream>. Ancak std::setprecision/std::setw/std::setfill/ etc gibi şeyleri kullanmak için eklemeniz gerekir <iomanip>.


44

Akışı onaltılık olarak yazdırmak üzere hexdeğiştirmek için manipülatörü kullanın :

cout << hex << a;

Varsayılan olarak, onaltılık karakterler küçük harfle verilir. Büyük harf yapmak için uppercasemanipülatörü kullanın :

cout << hex << uppercase << a;

Çıktıyı daha sonra tekrar küçük harfe değiştirmek için nouppercasemanipülatörü kullanın :

cout << nouppercase << b;

2
Is nouppercaseondalık çıkış geri değişecek?
— Cœur

Sadece çeşitli not eklemek için, yukarıdaki pasaj, "elma" girişinin "APPLE" olmasını sağlamaz.
— eigenfield

25

Tek bir onaltılık sayı yazdırmak ve ardından ondalık sayıya geri dönmek istiyorsanız, bunu kullanabilirsiniz:

std::cout << std::hex << num << std::dec << std::endl;

13

Bunun OP'nin istediği şey olmadığını anlıyorum, ancak yine de bunun printf ile nasıl yapılacağına işaret etmeye değer olduğunu düşünüyorum. Neredeyse her zaman std :: cout yerine kullanmayı tercih ederim (önceden C geçmişi olmasa bile).

printf("%.2X", a);

'2' hassasiyeti, 'X' veya 'x' büyük / küçük harf durumunu tanımlar.


4
Uzun zamandır printf'e karşı cout savaşı var. Tabii ki cout, ostream'den elde ettiği güzel özelliğe sahiptir ve tüm soyutlama faydalarını elde eder. C akış nesneleri kavramına sahip değildir ve bu nedenle printf ve fprintf 2 farklı komuttur. Gerçekten, stdout bir DOSYA * olsaydı, C'de güzel olurdu. İşleri kolaylaştırırdı.
— rlbond

11
@rlbond stdout C dilinde bir DOSYA *
— Étienne

4
Bu yüzden printf("hello\n")eşdeğerdir fprintf(stdout, "hello\n"). Daha kullanışlı bir şekilde, bağımsız değişken alan bir işleve geçebilirsiniz stdout(veya stdin, veya stderr) FILE*.
— Keith Thompson

12

Kullanabileceğiniz farklı türde bayraklar ve maskeler de vardır. Lütfen bakın fazla bilgi için http://www.cplusplus.com/reference/iostream/ios_base/setf/ .

#include <iostream>
using namespace std;

int main()
{
    int num = 255;
    cout.setf(ios::hex, ios::basefield);
    cout << "Hex: " << num << endl;

    cout.unsetf(ios::hex);
    cout << "Original format: " << num << endl;

    return 0;
}

5
Bu kodun davranışının tanımsız olduğunu düşünüyorum. Setf, ios :: dec (standart akımlar için varsayılan) dahil olmak üzere ios :: basefield bitlerini temizler ve yalnızca ios :: hex'i ayarlar. İos :: hex ayarlanmadığında, ios :: basefield'daki her bit ayarlanmaz. İkinci sefer nasıl basıldı? bitlerin ayarlanmamış olduğuna dair kanıt: ideone.com/fYXyh6 . Buna, Thinking in C ++ vol 2 page 189'a göre ios :: floatfield için izin verilir, ancak ios :: basefield için aynı şeyi söylemez.
— Joel Sjögren

11

std::hex size onaltılık formatlama sağlar, ancak durum bilgisi olan bir seçenektir, yani durumu kaydetmeniz ve geri yüklemeniz gerekir, aksi takdirde gelecekteki tüm çıktıları etkiler.

Saf bir şekilde geri dönmek std::dec, yalnızca bayrakların daha önce bulunduğu yerdeyse iyidir, bu durum böyle olmayabilir, özellikle de bir kitaplık yazıyorsanız.

#include <iostream>
#include <ios>

...

std::ios_base::fmtflags f( cout.flags() );  // save flags state
std::cout << std::hex << a;
cout.flags( f );  // restore flags state

Bu, Greg Hewgill'in cevabını ve başka bir sorudaki bilgileri birleştirir .


4

Onaltılık formatta görüntülenecek tamsayı değişkenini formatlamak için std::uppercaseve tuşlarını kullanın .std::hexa

#include <iostream>
int main() {
   int a = 255;

   // Formatting Integer
   std::cout << std::uppercase << std::hex << a << std::endl; // Output: FF
   std::cout << std::showbase  << std::hex << a << std::endl; // Output: 0XFF
   std::cout << std::nouppercase << std::showbase  << std::hex << a << std::endl; // Output: 0xff

   return 0;
}

2

C ++ 20 std::format

std::coutDevleti şu şekilde kirletmediği için, şu anda bence en temiz yöntem std::hex:

#include <format>
#include <string>

int main() {
    std::cout << std::format("{:x} {:#x} {}\n", 16, 17, 18);
}

Beklenen çıktı:

10 0x11 18

Henüz GCC 10.0.1, Ubuntu 20.04'te uygulanmadı, bu yüzden henüz test etmedim.

Belgelendi:

Daha fazla bilgi için: std :: sprintf gibi string formatlama

Pre-C ++ 20: temiz bir şekilde yazdırın ve std::coutönceki duruma geri yükleyin

main.cpp

#include <iostream>
#include <string>

int main() {
    std::ios oldState(nullptr);
    oldState.copyfmt(std::cout);
    std::cout << std::hex;
    std::cout << 16 << std::endl;
    std::cout.copyfmt(oldState);
    std::cout << 17 << std::endl;
}

Derleyin ve çalıştırın:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

Çıktı:

10
17

Daha fazla ayrıntı: std :: cout'un durumunu değiştirdikten sonra geri yükleyin

GCC 10.0.1, Ubuntu 20.04'te test edilmiştir.

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.