snprintf c++ alternative - c++

How can I convert this code from C into C++ ?
char out[61]; //null terminator
for (i = 0; i < 20; i++) {
snprintf(out+i*3, 4, "%02x ", obuf[i])
}
I can't find any alternative for snprintf.

Use stringstream class from <sstream>.
E.g.:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;
int main()
{
stringstream ss;
for (int i = 0; i < 20; i++) {
ss << setw(3) << i;
}
cout << "Resulting string: " << endl;
cout << ss.str() << endl;
printf("Resulting char*: \n%s\n", ss.str().c_str() );
return 0;
}

This code is valid C++11, if you have #include <cstdio> and type std::snprintf (or using namespace std;).
No need to "fix" what isn't broken.

You can use Boost.Format.
#include <boost/format.hpp>
#include <string>
std::string out;
for (size_t i=0; i<20; ++i)
out += (boost::format("%02x") % int(obuf[i])).str();

You can convert this code from C to C++ easily with standard library's std::stringstream and iomanip I/O stream manipulators:
#include <sstream>
#include <iomanip>
...
std::ostringstream stream;
stream << std::setfill('0') << std::hex;
for (const auto byte : obuf)
stream << std::setw(2) << byte;
const auto out = stream.str();

Related

Build incremental std::string

I try to build an std::string in the form of "start:Pdc1;Pdc2;Pdc3;"
With following code I can build the repeated "Pdc" and the incremental string "123" but I'm unable to combine the two strings.
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
int main()
{
std::ostringstream ss;
std::string hdr("start:");
std::fill_n(std::ostream_iterator<std::string>(ss), 3, "Pdc;");
hdr.append(ss.str());
std::string v("abc");
std::iota(v.begin(), v.end(), '1');
std::cout << hdr << std::endl;
std::cout << v << std::endl;
std::cout << "Expected output: start:Pdc1;Pdc2;Pdc3;" << std::endl;
return 0;
}
How can I build this string? Preferable without a while or for loop.
The expected output is: start:Pdc1;Pdc2;Pdc3;
std::strings can be concatenated via their operator+ (or +=) and integers can be converted via std::to_string:
std::string res("start:");
for (int i=0;i<3;++i){
res += "Pdc" + std::to_string(i+1) + ";";
}
std::cout << res << "\n";
If you like you can use an algorithm instead of the handwritten loop, but it will still be a loop (your code has 2 loops, but only 1 is needed).
Code to generate your expected string, though with a small for loop.
#include <iostream>
#include <string>
#include <sstream>
std::string cmd(const std::size_t N)
{
std::ostringstream os;
os << "start:";
for(std::size_t n = 1; n <= N; ++n) os << "Pdc" << n << ";";
return os.str();
}
int main()
{
std::cout << cmd(3ul);
return 0;
}

I want to store the following line into a string array in C++. How can I do it?

I want to make a string array in C++ which holds 0000, 0001, 00002, 0003 and so on up to 9999. Is there any way to implement this with loop. I do not want to take input manually. I want something like this.
for(i=0;i<10000;i++)
str[i] = i;
https://ideone.com/4kayTz
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>
int main() {
std::vector<std::string> str(10000);
std::stringstream ss;
ss << std::setfill('0');
for (int i = 0; i < 10000; i++) {
ss << std::setw(4) << i;
str[i] = ss.str();
ss.str(""); // Reset/make empty the string stream.
std::cout << str[i] << std::endl;
}
return 0;
}

C++ how to convert unsigned char array to string?

I'm testing a piece of code that performs a hash operation (sha256) of a binary file and I've got something like this:
for(i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", c[i]);
This prints something like:
12b64492d18aa37d609f27cb02ce5ba381068d1ef5625193df68451c650a2b8d
I'm asking how can I do to get the string shown below into a string variable in C++.
thanks
#include <iomanip>
#include <sstream>
#include <string>
std::ostringstream oss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
{
oss << std::hex << std::setw(2) << std::setfill('0') << +c[i];
}
auto str = oss.str();
For printing out hex values, you can use std::hex format; for setting width and fill character, use std::setw and std::setfill, which are part of <iomanip>.
As you do not show the data type of c, I suppose/suggest to use an unsigned integral type, e.g. unsigned char. I slightly adapted the code to make it self contained):
#define SHA256_DIGEST_LENGTH 256
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
unsigned char c[SHA256_DIGEST_LENGTH];
for (unsigned int i=0; i<SHA256_DIGEST_LENGTH; i++)
c[i]=i;
std::stringstream ss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)c[i];
}
std::cout << ss.str();
}
Output:
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
Just for comparison, here's the sprintf version:
#include <stdio.h>
#include <string>
std::string ss;
ss.resize(SHA256_DIGEST_LENGTH * 2 + 1); // includes space for terminating NUL
int used = 0;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
used += sprintf(&ss[used], "%02x", c[i]);
ss.resize(used);
Note that there's no harm in making the buffer larger than necessary initially because the final exact size is used, but if there's any possibility the buffer is too small then one must use snprintf and also pass the buffer space remaining (ss.size() - used).

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;
}
}

could you explain the reasons about output when using std::hex and std::wios::hex in C++

I have three programs.
the code of programA is shown below:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
int _tmain( void )
{
wstringstream s2;
TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
for (int i = 0; i < 4; i++)
{
s2<< hex <<(unsigned int)waTemp2[i] << " ";
}
wstring strData2 = s2.str();
wcout << strData2.c_str() <<endl;
return 0;
}
here is the output:
a0 a1 a2 a3
the code of programB is shown below:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
int _tmain( void )
{
wstringstream s2;
TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
for (int i = 0; i < 4; i++)
{
s2<< hex << waTemp2[i] << " ";
}
wstring strData2 = s2.str();
wcout << strData2.c_str() <<endl;
return 0;
}
here is the output:
????
the code of the programC is shown below:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
wstringstream s2;
TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
for (int i = 0; i < 4; i++)
{
s2 << std::wios::hex <<(unsigned int)waTemp2[i] << " ";
}
wstring strData2 = s2.str();
wcout<< strData2.c_str() <<endl;
return 0;
}
here is the output:
2048160 2048161 2048162 2048163
could you tell me the reasons the difference between std::wios::hex and std::hex, std::hex << waTemp2[i] and std::hex << (unsigned int)waTemp2[i] resulted in different of the output.
thank you very much!
std::hex is a manipulator. It sets the stream to output hex when you pass an integer. It is equivalent to calling setf(std::wios::hex, std::wios::basefield); on the stream (assuming wide streams). For example, try the following modification of your code. You should see the same results.
wchar_t waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
s2.setf(std::wios::hex, std::wios::basefield);
for (int i = 0; i < 4; i++)
{
s2 << (unsigned)waTemp2[i] << " ";
}
std::wios::hex is a constant number used as a bitmask flag. Do not confuse it with a manipulator which sets the stream.
On coliru for example the following prints 8.
std::cout << std::wios::hex;
It is used as a bitmask to update the format flags on the stream. It will defined something like the following (see the real definition in libstdc++ here):
enum fmtflags
{
_hex = 1L << 3,
};
class ios_base
{
static const fmtflags hex = _hex;
};
The reason you are seeing 2048160 2048161 2048162 2048163 is it is just printing out the numbers of std::wios::hex and (unsigned int)waTemp2[i]. Add a space in between to see s2 << std::wios::hex << " " << (unsigned int)waTemp2[i] << " ";
The problem with s2 << hex << waTemp2[i] << " "; is std::hex is only used for integers. Since wchar_t is not an integer, it just prints the corresponding character.