• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak wypisać liczby w formacie binarnym do terminala?

0 głosów
764 wizyt
pytanie zadane 16 marca 2022 w C i C++ przez osobliwy nick Użytkownik (900 p.)
edycja 16 marca 2022 przez osobliwy nick

Mam program, który zwraca pewien 64-bitowy result i mogę to wypisać:

std::cout << result << "\n";

Ale potrzebuję to wypisać w formacie binarnym. Liczby powinny się wyświetlać jako krzaki. W Pythonie na przykład dla liczb 16-bitowych robię to tak:

binary = struct.pack('H', result)
sys.stdout.buffer.write(binary)

Jak to zrobić w c++? Dodam, że nic nie rozumiem z tego co znalazłem na ten temat w Internecie, same przykłady są tak skomplikowane, że nie wiem o co w nich chodzi. Kiedyś ktoś pokazywał mi, że robił to zdaje się tak:

fwrite(buf, 1, sizeof(buf), stdout);

Ale wstawienie pod buf wyniku result nie działa, nie wiem też, czy ten kod ma w ogóle sens w tym kontekście. U niego buf[i] było chyba jakąś tablicą, nie wiem, czy nie tablicą złożoną z bitów danej liczby.

Ale cięcie liczby na pojedyncze bity i to w pętli wydaje się bardzo skomplikowane, tylko po to by wypisać ją binarnie. Choć nie zdziwiłbym się, gdyby nie było innego wyjścia.

1 odpowiedź

+1 głos
odpowiedź 16 marca 2022 przez adrian17 Mentor (355,240 p.)
wybrane 16 marca 2022 przez osobliwy nick
 
Najlepsza

Ale cięcie liczby na pojedyncze bity i to w pętli wydaje się bardzo skomplikowane

Nie bity, bajty.

Wystarczy że weźmiesz wskaźnik na swoją liczbę i przerzutujesz go na `char*`. (albo zwykłym castem z nawiasami, albo z `reinterpret_cast`). Wtedy możesz to traktować jako wskaźnik na tablicę bajtów (o rozmiarze `sizeof(result)`).

komentarz 16 marca 2022 przez adrian17 Mentor (355,240 p.)
Może i skompilowałeś, ale próbujesz teraz uruchomić plik tekstowy.cpp z kodem, a nie zbudowany program wykonywalny.
komentarz 16 marca 2022 przez osobliwy nick Użytkownik (900 p.)

Uruchomiłem to, ale wygląda na to, że coś nie działa w samym:

char *c = reinterpret_cast<char*>(&result);
std::cout << c;

Tak podawane liczby nie zdają testów, które podawane z programu w Pythonie zdają testy. Wygląda na to, jakby regularnie były tam dodawane jakieś znaki. Może skoro result to liczby 16-bitowe (bo akurat takie rozpatruję w nowym programie), a trafi się liczba mniejsza niż 16-bitów, na przykład 11, to miejsca pustych bitów są zapełniane zerami? 

Takie mam przeczucie, nie widzę bowiem innej możliwości, by dwa identyczne programy zachowywały się inaczej (produkują dokładnie te same liczby, natomiast binarny output programów jest najwyraźniej inny).

1
komentarz 16 marca 2022 przez adrian17 Mentor (355,240 p.)
edycja 16 marca 2022 przez adrian17
Do wypisywania surowych nie-tekstowych danych na strumień powinieneś tak jak w Pythonie użyć write():

https://en.cppreference.com/w/cpp/io/basic_ostream/write

niżej zresztą jest przykład dokładnie tego co chcesz zrobić.
komentarz 16 marca 2022 przez osobliwy nick Użytkownik (900 p.)
Faktycznie, teraz działa, choć nie rozumiem jeszcze jaka jest różnica. Ale dopiero uczę się C++. To wszystko zgłębię w przyszłości. Teraz najważniejsze, że jestem w stanie kilka programów, które potrzebuję w stanie zaprogramować i przetestować. Dzięki za pomoc.
komentarz 16 marca 2022 przez Oscar Nałogowiec (29,420 p.)

W tym przykładzie z << korzystac z char * co jest traktowane jako napis C, zakończony zerem. Wystąpienie zera jest traktowane jako koniec napisu.

A to stare fwrite też można użyć:

fwrite(&result, 1, sizeof(result), stdout);

 

Tylko pamiętaj, że wypisywanie dziwnych znaków na terminal może go poprzestawiać, jak się trafią jakieś kody sterujące. Dla "bezpieczeństwa" możesz wyjście puścić przez potok na xxd (hexdump).

./program | xxd

 

Podobne pytania

0 głosów
4 odpowiedzi 1,934 wizyt
0 głosów
1 odpowiedź 1,205 wizyt

93,787 zapytań

142,750 odpowiedzi

323,421 komentarzy

63,392 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...