C++ How to output int as 32-bit binary? - c++

I want to output an int in 32-bit binary format. Is looping and shifting my only option?

Looping is a way. You can also use bitset library.
#include <iostream>
#include <bitset>
int main(int argc, char** argv) {
int i = -5, j = 5;
unsigned k = 4000000000; // 4 billion
std::cout << std::bitset<32>(i) << "\t" << std::bitset<32>(j) << std::endl;
std::cout << std::bitset<32>(k) << std::endl;
return 0;
}
And the output will be:
11111111111111111111111111111011 00000000000000000000000000000101
11101110011010110010100000000000

Related

c++ reading argv into unsigned char fixed size: Segmentation fault

I am trying to read command line argument into a fixed size unsigned char array. I get segmentation fault.
My code:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <memory.h>
unsigned char key[16]={};
int main(int argc, char** argv){
std::cout << "Hello!" << std::endl;
long a = atol(argv[1]);
std::cout << a << std::endl;
memcpy(key, (unsigned char*) a, sizeof key);
// std::cout << sizeof key << std::endl;
// for (int i = 0; i < 16; i++)
// std::cout << (int) (key[i]) << std::endl;
return 0;
}
What am I doing wrong?
To call the program:
compile: g++ main.cpp
Execute: ./a.out 128
You get SEGV because your address is wrong: you convert a value to an address. Plus the size is the one of the destination, should be the size of the source
The compiler issues a warning, that's never good, you should take it into account because that was exactly your error:
xxx.c:12:38: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
memcpy(key, (unsigned char*) a, sizeof key);
^
fix that like this:
memcpy(key, &a, sizeof(a));
BTW you don't have to declare key with 16 bytes. It would be safer to allocate it like this:
unsigned char key[sizeof(long)];
and when you print the bytes, iterate until sizeof(long) too, or you'll just print trash bytes in the end.
Here's a fix proposal using uint64_t (unsigned 64-bit integer from stdint.h which gives exact control on the size), zero initialization for your key and parsing using strtoll:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <memory.h>
#include <stdint.h>
unsigned char key[sizeof(uint64_t)]={0};
int main(int argc, char** argv){
std::cout << "Hello!" << std::endl;
uint64_t a = strtoll(argv[1],NULL,10);
memcpy(key, &a, sizeof a);
for (int i = 0; i < sizeof(key); i++)
std::cout << (int) (key[i]) << std::endl;
return 0;
}
(if you want to handle signed, just change to int64_t)
Test on a little endian architecture:
% a 10000000000000
Hello!
0
160
114
78
24
9
0
0
Looks like you are copying too much data.
I also added a &a for the memcpy.
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <memory.h>
unsigned char key[16]={};
int main(int argc, char** argv)
{
memset(key,0x0, sizeof(key));
std::cout << "Hello!" << std::endl;
long a = atol(argv[1]);
std::cout << a << std::endl;
// the size parameter needs to be the size of a
// or the lesser of the size of key and a
memcpy(key,(void *) &a, sizeof(a));
std::cout << "size of key " << sizeof(key) << "\n";
std::cout << "key " << key << "\n";
for (int i = 0; i < 16; i++)
std::cout << " " << i << " '" << ((int) key[i]) << "'\n";
return 0;
}

Convert mpz_t to binary representation

I'm using mpz_t for big numbers. I need to convert the mpz_t to binary representation. I tried to use the mpz_export, but the returned array contains only 0s.
mpz_t test;
mpz_init(test);
string myString = "173065661579367924163593258659639227443747684437943794002725938880375168921999825584315046";
mpz_set_str(test,myString.c_str(),10);
int size = mpz_sizeinbase(test,2);
cout << "size is : "<< size<<endl;
byte *rop = new byte[size];
mpz_export(rop,NULL,1,sizeof(rop),1,0,test);
Using gmpxx (since it's taged as c++)
#include <iostream>
#include <gmpxx.h>
int main()
{
mpz_class a("123456789");
std::cout << a.get_str(2) << std::endl; //base 2 representation
}
There should be equivalent function in plain GMP
You have a minor error in your code: sizeof(rop) is either 4 or 8, depending on whether a pointer is 4 or 8 bytes on your system. You meant to pass simply size, not sizeof(rop).
Here's some code that works for me, with g++ -lgmp -lgmpxx:
#include <stdio.h>
#include <iostream>
#include <gmpxx.h>
int main()
{
mpz_class a("173065661579367924163593258659639227443747684437943794002725938880375168921999825584315046");
int size = mpz_sizeinbase(a.get_mpz_t(), 256);
std::cout << "size is : " << size << std::endl;
unsigned char *rop = new unsigned char[size];
mpz_export(rop, NULL, 1, 1, 1, 0, a.get_mpz_t());
for (size_t i = 0; i < size; ++i) {
printf("%02x", rop[i]);
}
std::cout << std::endl;
}

C++ Looping with String Functions

I'm doodling with this implementation of SHA-256. I'm trying to write a program that produces sha(0), sha(1), ... but I'm unable to. Naively I tried
#include <iostream>
#include "sha256.h"
int main(int argc, char *argv[]){
for (int i=0; i < 4; i++)
std::cout << sha256("i");
return 0;
}
Of course, this doesn't produce sha256(0), sha256(1), ..., but rather interprets the i as the letter i, and not the integer variable i. Any advice on how to remedy this? Altering the function implentation itself is not feasible so I'm looking for another way. Clearly I don't know much C++ at all, but any advice would be much appreciated.
EDIT:
#include <iostream>
#include "sha256.h"
#include <sstream>
int main(int argc, char *argv[])
{
std::cout << "This is sha256("0"): \n" << sha256("0") << std::endl;
std::cout << "Loop: " << std::endl;
std::stringstream ss;
std::string result;
for (int i=0; i < 4; ++i)
{
ss << i;
ss >> result;
std::cout << sha256(result) << std::endl;
}
return 0;
You need to transform the number i to the string i accepted by SHA. A straightforward option is to use the std::to_string C++11 function
std::cout << sha256(std::to_string(i));
In case you don't have access to a C++11 compiler (you should have, it's almost 2016), you can glance at this excellent link:
Easiest way to convert int to string in C++
Quick (not the most efficient) way of doing it with a std::stringstream:
#include <iostream>
#include <sstream>
#include "sha256.h"
int main()
{
std::string result;
std::stringstream ss;
for (int i = 0; i < 4; i++)
{
ss << i;
ss >> result;
ss.clear(); // need to clear the eof flag so we can reuse it
std::cout << sha256(result) << std::endl;
}
}

Why is this C++ money_put<char> program not working?

I am experimenting with C++ locales, and cannot work out why the output is 0.05 instead of 4.98.
#include <iostream>
#include <vector>
#include <string>
#include <locale>
using namespace std;
int main(int argc, const char** argv) {
vector<string> locales;
locales.push_back("de_DE");
locales.push_back("en_AU");
locales.push_back("en_GB");
locales.push_back("zh_CN");
long double amount = 4.98;
for (size_t i = 0, s = locales.size(); i < s; ++i) {
if (locales[i] != "C") {
cout.imbue(locale(locales[i].c_str()));
cout << i << " (" << locales[i] << "): ";
const moneypunct<char>& mp = use_facet<moneypunct<char> >(cout.getloc());
const money_put<char>& mv = use_facet<money_put<char> >(cout.getloc());
cout << mp.curr_symbol();
ostreambuf_iterator<char> out(cout);
mv.put(out, false, cout, cout.fill(), amount);
cout << endl;
}
}
return 0;
}
The output of the program is below:
0 (de_DE): Eu0,05
1 (en_AU): $0.05
2 (en_GB): £0.05
3 (zh_CN): ¥0.05
What am I doing wrong?
The (simplified) answer is that the money_put<char>.put() function refers to a long double parameter called units. This is the units in cents, not dollars.
[locale.money.put.virtuals]
The argument units is transformed into a sequence of wide characters as if by
ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)
You can find exhaustive info on the cppreference page.

How to output an integer value in command line argument to characters of the equivalent length as the value in C++?

I got a value say 10 and i want to output this into xxxxxxxxxx (10 x). How do i do this?
The value 10 is passed in via the command line.
I have tried this, but it doesn't do what I want:
for (i = 1; i < argc; i++){
cout << argv[i++] << " " << argv[i] << endl;
} // i cant get the argv[i] to print out the value in 'x'
if (argc>1)
cout << string(atoi(argv[1]), 'x');
There is a way using the streams, but I don't know it offhand: it's something like cout.SetPrecision(). But the C way is to provide a format specification.
int
main (int argc, char **argv)
{
printf ("%*d\n", atoi(argv[1]), 10); // outputs 10 into fieldwidth given by parameter
}
This needs quite a bit of development to handle pathologies of input, but the basic concept works. * means use the next parameter as a field width.
You simply need
std::cout << std::string(10, 'x');
So fullblown:
#include <iostream>
#include <string>
#include <sstream>
int main(int argc, const char* args[])
{
if (argc>1)
{
std::istringstream iss(args[1]);
unsigned long i = 0;
iss >> i;
std::cout << std::string(i, 'x');
}
return 0;
}
See here