C++ Looping with String Functions - c++

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

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

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).

snprintf c++ alternative

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();

std::vector passed by reference is not passing from a function to main()

This question is very similar to some other questions that have been posted on here, but nonetheless, it does not seem to work when I implement previously suggested solutions. I am writing what should be some simple software that can be used to read in one column or multiple columns of data from a .txt file in a function and pass it to the main program for further calculations. The function call passes the file name to the function and reads in the data. Since this version only reads in one columns of data I could use a return function for this specific example, but I plan on expanding this to read in multiple columns of data so that is why I am using a void function. The column of test data is shown below.
103.816
43.984
2214.5
321.5
615.8
8.186
37.6
The for loop in the function Read_File reads back the data from the file perfectly indicating that the function works fine and properly reads in the data. However, when I try to display the same data using the same for loop in the main program i get an EXEC_BAD_ACCESS fault. To be clear the program compiles fine, but it is not passing the data to the main program, which indicates a pointer problem. Where am I going wrong with this? Any help would be greatly appreciated.
#include <vector>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <iterator>
class Read_Columnar_File {
public:
void Read_File(const std::string& file_name,std::vector<float>& Column1);
};
#include <iostream>
int main(int argc, const char * argv[]) {
int i;
std::vector<float> Column2;
Read_Columnar_File File1;
char str[20];
std::strcpy(str,"Test.txt");
File1.Read_File(str,Column2);
std::cout << std::endl;
for(i = 0; i < 7; i++) std::cout << Column2[i];
}
void Read_Columnar_File::Read_File(const std::string& file_name,std::vector<float>& Column1)
{
int i;
std::ifstream inp(file_name,std::ios::in | std::ios::binary);
if(inp.is_open()) {
std::istream_iterator<float> start((inp)), end;
std::vector<float> Column1(start,end);
for(i=0; i < 7; i++) std::cout << Column1[i] << std::endl;
}
else std::cout << "Cannot Open " << file_name << std::endl;
inp.close();
}
you are declaring a local variable std::vector<float> Column1(start,end); inside the function
the local variable is being assigned the values, so actual vector is not updated.
This will fix the issue. column1 is locally declared.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
class Read_Columnar_File {
public:
void Read_File(const std::string& file_name, std::vector<float>& Column1);
};
int main(int argc, const char * argv[]) {
int i;
std::vector<float> Column2;
Read_Columnar_File File1;
char str[20];
std::strcpy(str, "Test.txt");
File1.Read_File(str, Column2);
std::cout << std::endl;
for (i = 0; i < 7; i++) std::cout << Column2[i];
}
void Read_Columnar_File::Read_File(const std::string& file_name, std::vector<float>& Column1)
{
int i;
std::ifstream inp(file_name, std::ios::in | std::ios::binary);
if (inp.is_open()) {
std::istream_iterator<float> start((inp)), end;
Column1.assign(start, end);
for (i = 0; i < 7; i++) std::cout << Column1[i] << std::endl;
}
else std::cout << "Cannot Open " << file_name << std::endl;
inp.close();
}

is there a way to parse a INT to string/char* without using a stream?

There are sooo many posts about converting from int to string but they all really involve either just printing to the screen, or using ostringstream.
I was using ostringstream, but my company doesnt want me to use any streams because it has horrid runtimes.
I was doing this in a C++ file.
my issue is that i was going to, over the course of execution create millions of streams, write to the buffers, and then copy content into a string, as such:
ostringstream OS;
os << "TROLOLOLOLOL";
std::string myStr = os.str();
There is redundancy as it is making this buffer then copying it all over. UGH!
In C++11:
string s = std::to_string(42);
I did a benchmark a couple of weeks ago, and got those results (using clang and libc++ shipped with current Xcode):
stringstream took 446ms
to_string took 203ms
c style took 170ms
With the following code:
#include <iostream>
#include <chrono>
#include <sstream>
#include <stdlib.h>
using namespace std;
struct Measure {
chrono::time_point<chrono::system_clock> _start;
string _name;
Measure(const string& name) : _name(name) {
_start = chrono::system_clock::now();
}
~Measure() {
cout << _name << " took " << chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - _start).count() << "ms" << endl;
}
};
int main(int argc, const char * argv[]) {
int n = 1000000;
{
Measure m("stringstream");
for (int i = 0; i < n; ++i) {
stringstream ss;
ss << i;
string s = ss.str();
}
}
{
Measure m("to_string");
for (int i = 0; i < n; ++i) {
string s = to_string(i);
}
}
{
Measure m("c style");
for (int i = 0; i < n; ++i) {
char buff[50];
snprintf(buff, 49, "%d", i);
string s(buff);
}
}
return 0;
}
In C++11 you have std::to_string. Although it probably uses the stringstream technique under the hoods.
You should take a look at the performance chart of boost::lexical_cast:
http://www.boost.org/doc/libs/1_52_0/doc/html/boost_lexical_cast/performance.html
It compares lexical_cast to stringstream (with and without construction) and scanf/printf.
In most cases boost::lexical_cast is faster than scanf, printf, std::stringstream.
Reusing the stringstream buffer. Note, this is not thread safe.
#include <sstream>
#include <iostream>
#include <string>
template<class T>
bool str_to_type(const char *str, T &value) {
static std::stringstream strm;
if ( str ) {
strm << std::ends;
strm.clear();
strm.setf(std::ios::boolalpha);
strm.seekp(0);
strm.seekg(0);
strm << str << std::ends;
strm >> value;
return !strm.fail();
}
return false;
}
int main(int argc, char *argv[])
{
int i;
if (!str_to_type("42", i))
std::cout << "Error" << std::endl;
std::cout << i << std::endl;
return 0;
}