How can I convert const char* to integer in c++? - c++

I have these variables.
static constexpr int size{70};
const char* str;
std::array<int_least8_t, size> digits;
if str is "1110" I want it to be in digits [1,1,1,0]
int i=0;
while (*cci)
{
digits[i]=*cci; // I need some method to convert it
+cci;
i++;
}

I made example for you here
#include <iostream>
#include <array>
#include <string>
#include <algorithm>
static constexpr int size{70};
const char* str = "1110";
std::array<int_least8_t, size> digits;
int main()
{
int i = 0;
for(auto c = str; *c; ++c, ++i) {
digits[i] = *c - '0';
}
std::cout << "Count=" << i << std::endl;
std::for_each(std::begin(digits), std::begin(digits) + i, [](const auto& Value) {
std::cout << "Value=" << std::to_string(Value) << std::endl;
});
return 0;
}
Output:
Count=4
Value=1
Value=1
Value=1
Value=0
In MSVC compiler I use it looks like
typedef signed char int_least8_t;

Related

Can I create constexpr strings with functions?

I have a method that creates a file header with a given comment symbol, depending on the output file type. There are only a few supported file types, thus I want to create these headers at compile time. Can I make these as a constexpr ?
std::string create_header(const std::string &comment_symbol) {
std::string div(15, '-');
std::string space(2, ' ');
std::stringstream hdr;
hdr << comment_symbol << space << " Begin of File." << std::endl;
hdr << comment_symbol << space << div << std::endl;
return hdr.str();
}
std::string c_header() { return create_header("//"); }
std::string python_header() { return create_header("#");
Can I create constexpr strings with functions?
You can't return std::string, cause it allocates memory.
Can I make these as a constexpr ?
Sure, something along:
#include <array>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
template<size_t N> constexpr
auto create_header(const char (&comment_symbol)[N]) {
const char one[] = " Begin of File.\n";
const char two[] = " -\n";
std::array<char,
N + (sizeof(one) - 1) +
N + (sizeof(two) - 1) + 1
> ret{};
auto it = ret.begin();
for (const char *i = comment_symbol; *i; ++i) *it++ = *i;
for (const char *i = one; *i; ++i) *it++ = *i;
for (const char *i = comment_symbol; *i; ++i) *it++ = *i;
for (const char *i = two; *i; ++i) *it++ = *i;
return ret;
}
std::string c_header() {
constexpr auto a = create_header("//");
return std::string{a.begin(), a.end()};
}
int main() {
std::cout << c_header() << '\n';
}

Replace a loop to retrieve the index of the first element in an array

Is there a better way to search for the index of the first element using a predicate?
// ... this code looks a bit long to me. Anyway to do better?
auto it = std::find_if(collection + startAt,
collection + COLLECTION_SIZE,
[](const char* line) { return strlen(line) <= 10; });
int idx = std::dist(collection, it); //= it - collection;
This is my attempt to refactor the C-style code below:
for (posEmptyItem = startAt; strlen(collection[posEmptyItem]) > 10; posEmptyItem++) {}
std::cout << posEmptyItem << std::endl;
Here a complete example of
#include "stdafx.h"
#include <cstring>
#include <iostream>
#include <algorithm>
#define COLLECTION_SIZE 123
int main()
{
char* collection[COLLECTION_SIZE]{ "time11,time2,time3",
"time12,time2,time3",
"time13,time2,time3",
"time14,time2,time3",
"time15,time2,time3",
"x\n",
"" };
auto startAt = 2;
int posEmptyItem;
// legacy code
for (posEmptyItem = startAt; strlen(collection[posEmptyItem]) > 10; posEmptyItem++) {}
std::cout << posEmptyItem << std::endl;
// replace the loop to search an index by calling to standard library
auto it = std::find_if(collection + startAt,
collection + COLLECTION_SIZE,
[](const char* line) { return strlen(line) <= 10; });
posEmptyItem = it - collection;
std::cout << posEmptyItem << std::endl;
return 0;
}

How to use count() function in a vector<struct> according to specific criteria

I have a vector of type struct with some elements, and trying to count the number of occurrences of an element(value) in its corresponding column of the vector. I know how to count on a simple vector, e.g on vector of type string. But am stuck on vector<struct>. Any possible solution or suggestion?
Sample code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
struct my_struct
{
std::string first_name;
std::string last_name;
};
int main()
{
std::vector<my_struct> my_vector(5);
my_vector[0].first_name = "David";
my_vector[0].last_name = "Andriw";
my_vector[1].first_name = "Jhon";
my_vector[1].last_name = "Monta";
my_vector[2].first_name = "Jams";
my_vector[2].last_name = "Ruth";
my_vector[3].first_name = "David";
my_vector[3].last_name = "AAA";
my_vector[4].first_name = "Jhon";
my_vector[4].last_name = "BBB";
for(int i = 0; i < my_vector.size(); i++)
{
int my_count=count(my_vector.begin(), my_vector.end(),my_vector[i].first_name);
/*I need help to count the number of occerencess of each "First_name" in a vector
For example: First_Name:- David COUNT:- 2 ...and so on for each first_names*/
std::cout << "First_Name: " << my_vector[i].first_name << "\tCOUNT: " << my_count << std::endl;
}
return 0;
}
but, the same code for a vector of type string,std::vector<std::string> works properly. see below:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> my_vector;
my_vector.push_back("David");
my_vector.push_back("Jhon");
my_vector.push_back("Jams");
my_vector.push_back("David");
my_vector.push_back("Jhon");
for(int i = 0; i < my_vector.size(); i++)
{
int my_count = count(my_vector.begin(), my_vector.end(),my_vector[i]); //this works good
std::cout << "First_Name: " << my_vector[i] << "\tCOUNT: " << my_count << std::endl;
}
return 0;
}
You have to use std::count_if with correct predicate:
int my_count = std::count_if(my_vector.begin(), my_vector.end(),
[&](const my_struct& s) {
return s.first_name == my_vector[i].first_name;
});
Demo
The functor to replace lambda in C++03:
struct CompareFirstName
{
explicit CompareFirstName(const std::string& s) : first_name(s) {}
bool operator () (const my_struct& person) const
{
return person.first_name == first_name;
}
std::string first_name;
};
and then
int my_count = std::count_if(my_vector.begin(), my_vector.end(),
CompareFirstName(my_vector[i].first_name));
Demo

How to split a string and get I want in c++?

There is a string like this: M90I4D7
I need to push it in to this kind of struct:
struct CigarOp {
char Type; //!< CIGAR operation type (MIDNSHPX=)
uint32_t Length; //!< CIGAR operation length (number of bases)
//! constructor
CigarOp(const char type = '\0',
const uint32_t& length = 0)
: Type(type)
, Length(length)
{ }
};
which means I need to split it into 3 groups and each of them is a CigarOp( 'M' ,90 'I', 4 'D' ,7 )
Assuming that the string is of the form ([A-Z][0-9]+)*, you could quite simply do something like this:
#include <sstream>
...
std::vector<CigarOp> cigars;
std::istringstream parser("M90I4D7");
char c;
std::uint32_t l;
while(parser >> c >> l) {
cigars.push_back(CigarOp(c, l));
}
Note that this code doesn't do any sort of validation. If validation is necessary, one way to achieve it is to use Boost.Spirit (found on http://boost.org):
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <cstdint>
#include <iostream>
struct CigarOp {
char Type;
std::uint32_t Length;
};
BOOST_FUSION_ADAPT_STRUCT(CigarOp, (char, Type) (std::uint32_t, Length))
int main() {
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::char_;
using boost::spirit::qi::uint_;
using boost::spirit::qi::standard::space;
std::vector<CigarOp> cigars;
std::string s = "M90I4D7";
std::string::const_iterator first = s.begin(), last = s.end();
bool r = phrase_parse(first, last, *(char_ >> uint_), space, cigars);
if(r && first == last) {
// string was well-formed
for(auto const &cigar : cigars) {
std::cout << cigar.Type << ", " << cigar.Length << '\n';
}
}
}
how about:
#include <cstdio>
#include <cctype>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
struct CigarOp {
char op; //!< CIGAR operation type (MIDNSHPX=)
int size; //!< CIGAR operation length (number of bases)
static int parse(const char* s,vector<CigarOp>& v)
{
char* p=(char*)(s);
while(*p!=0)
{
char* endptr;
CigarOp c;
c.op = *p;
if(!isalpha(c.op)) return -1;
++p;
if(!isdigit(*p)) return -1;
c.size =strtol(p,&endptr,10);
if(c.size<=0) return -1;
v.push_back(c);
p=endptr;
}
return 0;
}
};
int main(int argc,char** argv)
{
vector<CigarOp> cigar;
if(CigarOp::parse("M90I4D7",cigar)!=0) return -1;
for(size_t i=0;i< cigar.size();++i)
{
cout << cigar[i].op << ":" << cigar[i].size << endl;
}
return 0;
}
btw , for bioinformatics, you should ask biostars.org.

Multiplying a string by an int in C++

What do I have to do so that when I
string s = ".";
If I do
cout << s * 2;
Will it be the same as
cout << "..";
?
std::string has a constructor of the form
std::string(size_type count, char c);
that will repeat the character. For example
#include <iostream>
int main() {
std::string stuff(2, '.');
std::cout << stuff << std::endl;
return 0;
}
will output
..
I used operator overloading to simulate this behavior in c++.
#include <iostream>
#include <string>
using namespace std;
/* Overloading * operator */
string operator * (string a, unsigned int b) {
string output = "";
while (b--) {
output += a;
}
return output;
}
int main() {
string str = "abc";
cout << (str * 2);
return 0;
}
Output:
abcabc
No, std::string has no operator *. You can add (char, string) to other string. Look at this http://en.cppreference.com/w/cpp/string/basic_string
And if you want this behaviour (no advice this) you can use something like this
#include <iostream>
#include <string>
template<typename Char, typename Traits, typename Allocator>
std::basic_string<Char, Traits, Allocator> operator *
(const std::basic_string<Char, Traits, Allocator> s, size_t n)
{
std::basic_string<Char, Traits, Allocator> tmp = s;
for (size_t i = 0; i < n; ++i)
{
tmp += s;
}
return tmp;
}
template<typename Char, typename Traits, typename Allocator>
std::basic_string<Char, Traits, Allocator> operator *
(size_t n, const std::basic_string<Char, Traits, Allocator>& s)
{
return s * n;
}
int main()
{
std::string s = "a";
std::cout << s * 5 << std::endl;
std::cout << 5 * s << std::endl;
std::wstring ws = L"a";
std::wcout << ws * 5 << std::endl;
std::wcout << 5 * ws << std::endl;
}
http://liveworkspace.org/code/52f7877b88cd0fba4622fab885907313
There is no predefined * operator that will multiply a string by an int, but you can define your own:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string operator*(const string& s, unsigned int n) {
stringstream out;
while (n--)
out << s;
return out.str();
}
string operator*(unsigned int n, const string& s) { return s * n; }
int main(int, char **) {
string s = ".";
cout << s * 3 << endl;
cout << 3 * s << endl;
}
They can't be multipled but I think you can write your own function to do this, something like -
#include <iostream>
#include <string>
std::string operator*(std::string s, size_t count)
{
std::string ret;
for(size_t i = 0; i < count; ++i)
{
ret = ret + s;
}
return ret;
}
int main()
{
std::string data = "+";
std::cout << data * 10 << "\n";
}
It's probably not the best idea though, it will be very confusing to anyone looking at the code and not expecting this,
Strings cannot be multiplied.
If s is a char
'.' // This has ASCII code 46
then
cout << (char)((int)s * 2);
will give you
'/' // This has ASCII code 92
Like JRG did, but in a single line
std::cout << std::string(70,'-') << std::endl;
This will create a string, filled with - (dashes), 70 characters long, and breaking the line at the end with std::endl;
You can do this:
#include <iostream>
using namespace std;
int main()
{
string text, new_text;
int multiply_number;
cin >> text >> multiply_number;
/*
First time in the 'for' loop: new_text = new_text + text
new_text = "" + "your text"
new_text = "your text"
Second time in the 'for' loop: new_text = new_text + text
new_text = "your text" + "your text"
new_text = "your textyour text"...n times
*/
for(int i=0; i<multiply_number; i++)
{
new_text += text;
}
cout << new_text << endl; // endl="\n"
system("pause");
return 0;
}
In Python you can multiply string like this:
text = "(Your text)"
print(text*200)
std::string StrMultiply(const char* str, size_t count) {
size_t stringsize = strlen(str);
size_t buffersize = stringsize * count + 1;
string res(buffersize,'\0');
char* end = res._Unchecked_end();
char* offset = res._Unchecked_begin();
for (size_t i = 0;i < count; offset += stringsize,i++)
{
memcpy(offset, str, stringsize);
}
// mark the end
res[buffersize - 1] = '\0';
return res;
}
inline std::string operator*(std::string left, size_t right) {
return StrMultiply(left.c_str(), right);
}
here is a ram-friendly solution, 10 times faster than using stringstreams or string::append
It's surprising that nobody talked about this yet. For assigning char*int to a variable, you can do str.assign(n, char). https://en.cppreference.com/w/cpp/string/basic_string/assign
For example, str.assign(2, 's') would yield ss for the value of str. Other methods to actually achieve the objective have already been mentioned.