Convert Marathi script (non-arabic) numbers to arabic numbers - c++

If we get value from edit box as Marathi '१.२' then I want this value as 1.2 in float format, I tried _wtof () but it failed it returned only 0. Its work same as _wtoi (). It's ok but -_wtof ()? Please suggest anything another function.

Actually std::stof and std::stod work just fine in Visual Studio 2015
#include <iostream>
#include <string>
double convert(const std::wstring src)
{
double f = 0;
try {
f = std::stod(src);
}
catch (...)
{
//error, out of range or invalid string
}
return f;
}
int main()
{
std::cout << std::setprecision(20);
std::cout << convert(L"१२३४५६७८९.१२३४५६७८९") << "\n";
std::cout << convert(L"१.२") << "\n";
return 0;
}
But _wtof doesn't work. You can use these methods if there is incompatibility in earlier version:
double convert(const std::wstring src)
{
std::wstring map = L"०१२३४५६७८९";
//convert src to Latin:
std::wstring result;
for (auto c : src)
{
int n = map.find(c);
if (n >= 0)
result += (wchar_t)(n+ (int)(L'0'));
else
result += c;
}
double n = 0;
try { n = std::stof(result); }
catch (...)
{
std::wcout << L"error" << result << "\n";
}
return n;
}
int main()
{
std::cout << convert(L"१.१") << "\n";
std::cout << convert(L"१.२") << "\n";
return 0;
}
or using CString:
double convert(const CString src)
{
CString map = L"०१२३४५६७८९";
//convert src to Latin:
CString result;
for (int i = 0; i < src.GetLength(); i++)
{
int n = map.Find(src[i]);
if (n >= 0)
result += (wchar_t)(n + (int)(L'0'));
else
result += src[i];
}
return _wtof(result.GetString());
}

Related

Collecting many printf calls in a single string

I am dealing with some code that performs RC4 encryption algorithm with some params passed into the function. From there I am trying to append the generated hash to an empty string but have failed with a few of my attempts. I had seen the use of snprintf() but how could I go about converting the code below to save what gets printed to a string?
for (size_t i = 0, len = strlen(plaintext); i < len; i++) {
printf("|x%02hhx| ", hash[i]);
}
Why not use C++.
#include <iomanip>
#include <iostream>
#include <sstream>
#include <cstring>
int main() {
char plaintext[] = "12345";
char hash[] = "123\xf0\x0f";
std::stringstream out;
for (size_t i = 0, len = strlen(plaintext); i < len; i++) {
out << "|x"
<< std::setfill('0') << std::setw(2) << std::setbase(16)
// ok, maybe this is the reason.
<< 0xff & hash[i]
<< "| ";
}
std::cout << out.str();
}
Just work with std::string::data after determining the size of the output of std::snprintf:
template<class...Args>
std::string PrintFToString(char const* format, Args...args)
{
std::string result;
char c;
int requiredSize = std::snprintf(&c, 1, format, args...);
if (requiredSize < 0)
{
throw std::runtime_error("error with snprintf");
}
result.resize(requiredSize);
int writtenSize = std::snprintf(result.data(), requiredSize+1, format, args...);
assert(writtenSize == requiredSize);
return result;
}
template<class...Args>
void AppendPrintFToString(std::string& target, char const* format, Args...args)
{
char c;
int requiredSize = std::snprintf(&c, 1, format, args...);
if (requiredSize < 0)
{
throw std::runtime_error("error with snprintf");
}
auto const oldSize = target.size();
target.resize(oldSize + requiredSize);
int writtenSize = std::snprintf(target.data() + oldSize, requiredSize+1, format, args...);
assert(writtenSize == requiredSize);
}
int main() {
std::cout << PrintFToString("|x%02hhx| ", 33) << '\n';
std::string output;
for (int i = 0; i != 64; ++i)
{
AppendPrintFToString(output, "|x%02hhx| ", i);
output.push_back('\n');
}
std::cout << output;
}
Note: If you know a reasonable upper bound for the number of characters of the output, you could use a char array allocated on the stack for output instead of having to use 2 calls to std::snprintf...

Hash multiple files

I'm trying to hash multiple files, but there is an error.
My files name start from Cheque 083654.tif - 08365122.tif
My code:
for (int i = 4; i < 123; i++)
{
stringstream file;
file<< "C:/Users/user/Desktop/datasets/Cheque 08365" << i << ".tif";
string filename = file.str();
cout << filename << '\n';
unsigned char *sha256digest = calculateSHA256(filename);
char *sha256hash = (char *)malloc(sizeof(char) * 65);
sha256hash[65] = '\0';
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(&sha256hash[i * 2], "%02x", sha256digest[i]);
}
printf("SHA256 HASH: %s\n", sha256hash);
system("pause");
}
The error states that no suitable conversion function from string to char * exists at the filename in:
unsigned char *sha256digest = calculateSHA256(filename);
How can I solve this error?
If calculateSHA256 returns std::string, that assignment is illegal in more ways than one. char * is just a pointer to that storage, string returned by function is a temporal object, which stops existing after semicolon. First, you have to save that string, second, to access its data by appropriate member function. There is no way to convert string directly to a pointer.
Or don't use pointer at all. You would find it better to avoid using C idioms at all.
std::string sha256digest = calculateSHA256(filename);
// FORMATTED OUTPUT
std::stringstream hashstr;
hashstr << std::hex << std::setfill('0');
for( auto x : sha256digest ) // this would iterate through entirety of string
{
hashstr << std::setw(2) << static_cast<int>(static_cast<unsigned char>(x));
}
std::string output;
hashstr >> output;
std::cout << "SHA256 HASH: " << output;
You do not need a stringstream to construct the filename. Use std::to_sting().
I think most of the simplification can be done inside your own calculateSHA256() function. Let it return a std::vector or std::string instead of a char*.
Here's an example where I let it return a std::vector<std::uint8_t> instead:
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <cstdint>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <string>
#include <vector>
// An EVP_MD_CTX helper class
class EvpMdCtx {
public:
explicit EvpMdCtx(const EVP_MD* type, ENGINE* impl = nullptr) : EvpMdCtx() {
if(init(type, impl) == 0)
throw std::runtime_error("EVP_DigestInit_ex failed");
}
EvpMdCtx() : ctx(EVP_MD_CTX_new()) {
if(ctx == nullptr) throw std::runtime_error("EVP_MD_CTX_new failed");
}
EvpMdCtx(const EvpMdCtx&) = delete;
EvpMdCtx& operator=(const EvpMdCtx&) = delete;
~EvpMdCtx() { EVP_MD_CTX_free(ctx); }
int init(const EVP_MD* type, ENGINE* impl = nullptr) {
return EVP_DigestInit_ex(ctx, type, impl);
}
int update(const void* d, size_t cnt) { return EVP_DigestUpdate(ctx, d, cnt); }
auto finalize() {
std::vector<std::uint8_t> md_value(EVP_MAX_MD_SIZE);
unsigned md_len;
if(EVP_DigestFinal_ex(ctx, md_value.data(), &md_len) == 0)
md_value.clear();
else
md_value.resize(md_len);
return md_value;
}
private:
EVP_MD_CTX* ctx;
};
std::vector<std::uint8_t> calculateSHA256(const std::string& filename) {
std::ifstream is(filename);
if(not is) return {};
EvpMdCtx ctx(EVP_sha256());
char buf[BUFSIZ]; // a buffer to fill
while(true) {
is.read(buf, std::size(buf));
auto len = is.gcount();
if(len > 0) {
if(ctx.update(buf, static_cast<size_t>(len)) == 0) return {};
} else {
break;
}
}
// finalize
return ctx.finalize();
}
int main() {
const std::string file = "C:/Users/user/Desktop/datasets/Cheque 08365";
for(int i = 4; i <= 122; ++i) {
std::string filename = file + std::to_string(i) + ".tif";
auto res = calculateSHA256(filename);
if(res.empty()) {
std::cout << "Failed: " << filename << '\n';
} else {
std::cout << std::hex << std::setfill('0');
for(auto v : res) {
std::cout << std::setw(2) << static_cast<int>(v);
}
std::cout << ' ' << filename << '\n';
}
}
}

Taking Each Individual Word From a String in C++

I am writing a method in C++ which will take a string of 2 or more words and output each individual word of the string separated by a second or so, using the sleep() method. I am trying to do this using a for loop and substrings. I am unsure also of the regexs which should be used, and how they should be used, to achieve the desired output.
I have reviewed this and this and find my question differs since I am trying to do this in a loop, and not store the individual substrings.
Input:
"This is an example"
Desired output:
"This " (pause) "is " (pause) "an " (pause) "example."
Use std::stringstream, no regular expressions required:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
stringstream ss("This is a test");
string s;
while (ss >> s) {
cout << s << endl;
}
return 0;
}
Also, see How do I tokenize a string in C++?
Here are a pair of implementations that don't involve creating any extraneous buffers.
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp> //for boost::copy
#include <chrono>
#include <iostream>
#include <string>
#include <experimental/string_view> //in clang or gcc; or use boost::string_ref in boost 1.53 or later; or use boost::iterator_range<char*> in earlier version of boost
#include <thread>
void method_one(std::experimental::string_view sv)
{
for(auto b = sv.begin(), e = sv.end(), space = std::find(b, e, ' ')
; b < e
; b = space + 1, space = std::find(space + 1, e, ' '))
{
std::copy(b, space, std::ostreambuf_iterator<char>(std::cout));
std::cout << " (pause) "; //note that this will spit out an extra pause the last time through
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void method_two(std::experimental::string_view sv)
{
boost::copy(
sv | boost::adaptors::filtered([](const char c) -> bool
{
if(c == ' ')
{
std::cout << " (pause) "; //note that this spits out exactly one pause per space character
std::this_thread::sleep_for(std::chrono::seconds(1));
return false;
}
return true;
})
, std::ostreambuf_iterator<char>(std::cout)
);
}
int main() {
const std::string s{"This is a string"};
method_one(s);
std::cout << std::endl;
method_two(s);
std::cout << std::endl;
return 0;
}
Live on coliru, if you're into that.
you can implement your own method:
//StrParse.h
#pragma once
#include <iostream>
static counter = 0;
char* strPar(char* pTxt, char c)
{
int lenAll = strlen(pTxt);
bool strBeg = false;
int nWords = 0;
for(int i(0); i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
}
if(strBeg)
{
nWords++;
strBeg = false;
}
}
int* pLens = new int[nWords];
int j = 0;
int len = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
len++;
}
if(strBeg)
{
pLens[j] = len;
j++;
strBeg = false;
len = 0;
}
}
char** pStr = new char*[nWords + 1];
for(i = 0; i < nWords; i++)
pStr[i] = new char[pLens[i] + 1];
int k = 0, l = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
pStr[k][l] = pTxt[i];
l++;
i++;
}
if(strBeg)
{
pStr[k][l] = '\0';
k++;
l = 0;
strBeg = false;
}
}
counter++;
if(counter <= nWords)
return pStr[counter - 1];
else
return NULL;
}
//main.cpp
#include "StrParse.h"
void main()
{
char* pTxt = " -CPlusPlus -programming -is -a - superb thing ";
char* pStr1 = NULL;
int i = 1;
char sep;
std::cout << "Separator: ";
sep = std::cin.get();
std::cin.sync();
while(pStr1 = strPar(pTxt, sep))
{
std::cout << "String " << i << ": " << pStr1 << std::endl;
delete pStr1;
i++;
}
std::cout << std::endl;
}

boost::fibonacci_heap copy constructor corrupts the source heap

I have a member function that prints a snapshot of a boost::fibonacci_heap
virtual void printSnapshot(std::ostream& ss) {
Heap heap(this->heap);
double prev_price = DBL_MAX;
while(heap.size() > 0) {
const Order& order = heap.top();
if(order.price != prev_price) {
if(prev_price != DBL_MAX) ss << std::endl;
ss << order.price << " | ";
}
ss << order.quantity << " ";
prev_price = order.price;
heap.pop();
}
ss << std::endl;
}
I call this member function in another member function, which does
while(std::getline(stream, line)) {
... // do something on this->heap.
this->printSnapshot(std::cout);
}
Since the heap is created through a copy constructor at the beginning of "printSnapshot", then "printSnapshot" should change this->heap. However, this program leads to segment fault, while the following does not:
while(std::getline(stream, line)) {
... // do something on this->heap.
// this->printSnapshot(std::cout);
}
Now, if we add a const keyword to the definition of printSnapshot, i.e.
virtual void printSnapshot(std::ostream& ss) const {
Heap heap(this->heap);
double prev_price = DBL_MAX;
while(heap.size() > 0) {
const Order& order = heap.top();
if(order.price != prev_price) {
if(prev_price != DBL_MAX) ss << std::endl;
ss << order.price << " | ";
}
ss << order.quantity << " ";
prev_price = order.price;
heap.pop();
}
ss << std::endl;
}
The segment fault disappears. How could this be explained?
The constructor of fibonacci_heap that takes a lvalue reference (non-const) apparently doesn't do the right things.
It's not documented what it should do: http://www.boost.org/doc/libs/1_55_0/doc/html/boost/heap/fibonacci_heap.html#idp21129704-bb
I assume this might be a reportable bug. I'll look into this a bit.
UPDATE Surprisingly the behaviour of this constructor is apparently equivalent to move-construction:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
/// \copydoc boost::heap::priority_queue::priority_queue(priority_queue &&)
fibonacci_heap(fibonacci_heap && rhs):
super_t(std::move(rhs)), top_element(rhs.top_element)
{
roots.splice(roots.begin(), rhs.roots);
rhs.top_element = NULL;
}
fibonacci_heap(fibonacci_heap & rhs):
super_t(rhs), top_element(rhs.top_element)
{
roots.splice(roots.begin(), rhs.roots);
rhs.top_element = NULL;
}
The latter has the weird side-effect of simply removing all roots from the original (intrusive) list. This looks like a clear-cut bug.
Simply removing this constructor makes the code work.
The essential workaround is to avoid the lvalue-ref constructor:
Heap cloned(static_cast<Heap const&>(this->heap));
Meanwhile here's a self-contained reproducer:
#include <boost/heap/fibonacci_heap.hpp>
#include <iostream>
#include <random>
namespace {
#undef DBL_MAX
static double DBL_MAX = std::numeric_limits<double>::max();
std::mt19937 rng;
//std::uniform_real_distribution<double> dist(100, 4000);
std::discrete_distribution<int> dist({1,1,1,1,1,1});
static auto price_gen = [&] {
static double values[] = {52.40, 12.30, 87.10, 388., 0.10, 23.40};
return values[dist(rng)];
};
}
struct Order {
double price = price_gen();
unsigned quantity = rand() % 4 + 1;
double subtotal() const { return price * quantity; }
bool operator<(Order const& other) const { return subtotal() < other.subtotal(); }
};
using Heap = boost::heap::fibonacci_heap<Order>;
struct Y {
virtual void printSnapshot(std::ostream &ss) {
//Heap cloned(static_cast<Heap const&>(this->heap));
Heap cloned(this->heap);
double prev_price = DBL_MAX;
while (cloned.size() > 0) {
const Order &order = cloned.top();
if (order.price != prev_price) {
if (prev_price != DBL_MAX)
ss << std::endl;
ss << order.price << " | ";
}
ss << order.quantity << " ";
prev_price = order.price;
cloned.pop();
}
ss << std::endl;
}
void generateOrders() {
for (int i=0; i<3; ++i) {
heap.push({});
}
}
Heap heap;
};
int main() {
Y y;
for(int i=0; i<10; ++i) {
y.generateOrders();
y.printSnapshot(std::cout);
}
}

How to insert spaces in a big number to make it more readable?

I came up with this, since other examples provided on stackoverflow were in C#
string number_fmt(ulong n)
{
// cout << "(" << n << ")" << endl;
char s[128];
sprintf(s, "%lu", n);
string r(s);
reverse(r.begin(), r.end());
int space_inserted = 0;
size_t how_many_spaces = r.length() / 3;
if(r.length() % 3 != 0)
how_many_spaces += 1;
for(int i = 1; i < how_many_spaces; ++i)
{
r.insert(3 * i + space_inserted, " ");
space_inserted += 1;
}
reverse(r.begin(), r.end());
return r;
}
Do you know any better solution ?
I don't know about "better", but this version uses std::locale, etc.
#include <iostream>
#include <locale>
#include <sstream>
template<class Char>
class MyFacet : public std::numpunct<Char> {
public:
std::string do_grouping() const { return "\3"; }
Char do_thousands_sep() const { return ' '; }
};
std::string number_fmt(unsigned long n)
{
std::ostringstream oss;
oss.imbue(std::locale(oss.getloc(), new MyFacet<char>));
oss << n;
return oss.str();
}
int main() {
std::cout << number_fmt(123456789) << "\n";
}
EDIT: Of course, if your final goal is to print the values on an ostream, you can skip storing them in a string altogether.
#include <iostream>
#include <locale>
#include <sstream>
#include <cwchar>
template <class Char>
class MyFacet : public std::numpunct<Char> {
public:
std::string do_grouping() const { return "\3"; }
Char do_thousands_sep() const { return ' '; }
};
int main(int ac, char **av) {
using std::locale;
using std::cout;
// Show how it works to start with
cout << 123456789 << "\n";
// Switch it to spacey mode
locale oldLoc =
cout.imbue(locale(cout.getloc(), new MyFacet<char>));
// How does it work now?
cout << 456789123 << "\n";
// You probably want to clean up after yourself
cout.imbue(oldLoc);
// Does it still work?
cout << 789123456 << "\n";
}
This is already done by the locale.
The default local is "C" which does no formatting. But you can set it to your current language-specific local (as defined by your computer's setting by setting the current local as the first line of main).
int main()
{
std::locale::global(std::locale("")); // Set the default local of the machine
// Will be used by all streams.
// The "" will find the machine specific local
// and use that instead of the "C" locale
// Note: The C local should only be used for programmers.
// Alternatively you can imbue particular stream with the local
// To achieve a localized effect
// std::cout.imbue(std::locale(""));
// Now all you do is print the number.
std::cout << "123456789\n"; // This will print the number according to your local
} // For me US-en this is 123,456,789
// Your may very.
If you want to do something explicitly then you can set a facet in the local for printing numbers.
#include <iostream>
#include <locale>
#include <string>
template<typename CharT>
struct Sep : public std::numpunct<CharT>
{
virtual std::string do_grouping() const {return "\003";}
virtual CharT do_thousands_sep() const {return ':';}
};
int main()
{
std::cout.imbue(std::locale(std::cout.getloc(), new Sep <char>()));
std::cout << 123456789 << "\n"; // this prints 123:456:789
}
This one is different, but better is subjective. I think it's very succinct and clear what it's doing though:
string number_fmt(unsigned long long n, char sep = ',') {
stringstream fmt;
fmt << n;
string s = fmt.str();
s.reserve(s.length() + s.length() / 3);
// loop until the end of the string and use j to keep track of every
// third loop starting taking into account the leading x digits (this probably
// can be rewritten in terms of just i, but it seems more clear when you use
// a seperate variable)
for (int i = 0, j = 3 - s.length() % 3; i < s.length(); ++i, ++j)
if (i != 0 && j % 3 == 0)
s.insert(i++, 1, sep);
return s;
}
Using it like
cout << number_fmt(43615091387465) << endl;
prints
43,615,091,387,465
Admittedly, if one wanted to have the most possible efficient version and didn't mind specializing it for the case at hand, using a local char buffer can help a lot.
#include <iostream>
#include <string>
std::string format(unsigned long long i) {
char buffer[128]; // can be adapted more tightly with std::numeric_limits
char* p = buffer + 128;
*(--p) = '\0';
unsigned char count = 0;
while (i != 0) {
*(--p) = '0' + (i % 10);
i /= 10;
if (++count == 3) { count = 0; *(--p) = ' '; }
}
return p;
}
int main() {
std::cout << format(1234567890) << '\n';
}
In action at ideone:
1 234 567 890
(Key point: for number printing, go backward)
Not very optimal but small
QString str = QString::number(d);
for (int i = 3; str.size() > i; i += 4)
str.insert(str.size() - i, ' ');
If "better" means more efficient, you should:
use reserve on the output string (you know its size...)
avoid the insert in the middle of the string, because you have to copy a big part of the string each time you do that.
I would say something like this (untested):
std::string number_fmt (ulong n)
{
std::ostringstream buff;
buff << n;
std::string without_spaces = buff.str ();
std::string with_spaces;
with_spaces.reserve ((without_spaces.size () * 4) / 3);
std::size_t nb_inserted = 0;
for (auto it = without_spaces.rbegin (); it != without_spaces.rend (); ++it)
{
if (nb_inserted % 3 == 0 && nb_inserted != 0)
{
with_spaces.push_back (' ');
}
++ nb_inserted;
with_spaces.push_back (*it);
}
std::reverse (with_spaces.begin (), with_spaces.end ());
return with_spaces;
}