Multiplying a string by an int in C++ - 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.

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

Implementing an alphabet in C++

I'm making a code for cipher that reads alphabet in it's binary code. Is there a way to implement custom alphabet (not using ASCII)? For example alphabet={a,b,c,d,e,...,z,],[,.,..., ,-} and for each character there's a number 0,1,...,63. So, the bijetion will be from element of alphabet to 6 bit number.
How to make this implementation using simple functions in C++? I tried to make a strings length 1 and corresponding number using if statements and then plug them into .txt file, but it didn't work out.
string str1, ..., str63;
string sometext;
str1 = 'a';
// ...
cin >> sometext;
int k;
k = sometext.length();
string res;
ofstream out;
out.open("cipher.txt");
for (int i = 0; i < k; i++) {
res = sometext.substr(i, 1);
if (res == str1) {
res = '000000';
}
// ...
if (res == str63) {
res = '111111';
}
out << res;
}
I made a simple class Alphabet achieving your task. It uses std::unordered_map to store mapping between characters and binary representation, and uses this mapping to convert between those two representations. Also it computes binary representation. Class can be given any alphabet.
For testing I do two conversions between char and binary and output results to console. If requested values are out of range then std::exception is thrown.
Try it online!
#include <string>
#include <unordered_map>
#include <cmath>
#include <stdexcept>
#include <iostream>
class Alphabet {
public:
Alphabet(std::string const & _chars)
: chars(_chars) {
size_t num_bits = std::ceil(std::log(std::max(size_t(1), chars.size()))
/ std::log(2) - 1e-6);
for (size_t i = 0; i < chars.size(); ++i) {
std::string bin;
for (ptrdiff_t j = num_bits - 1; j >= 0; --j)
bin += i & (1 << j) ? "1" : "0";
c2b[chars[i]] = bin;
b2c[bin] = chars[i];
}
}
std::string ToBin(char c) const {
auto it = c2b.find(c);
if (it == c2b.end())
throw std::runtime_error("Character '" +
std::string(1, c) + "' not in alphabet!");
return it->second;
}
char ToChar(std::string const & bin) const {
auto it = b2c.find(bin);
if (it == b2c.end())
throw std::runtime_error("Binary '" + bin + "' is out of range!");
return it->second;
}
std::string const & Chars() const {
return chars;
}
private:
std::string chars;
std::unordered_map<char, std::string> c2b;
std::unordered_map<std::string, char> b2c;
};
int main() {
try {
Alphabet alph("abcdef{}123");
std::cout << alph.ToBin('f') << std::endl;
std::cout << alph.ToChar("0011") << std::endl;
std::cout << alph.Chars() << std::endl;
return 0;
} catch (std::exception const & ex) {
std::cout << "Exception: " << ex.what() << std::endl;
return -1;
}
}
Output:
0101
d
abcdef{}123

How can I convert const char* to integer in 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;

why can't i replace char on a string like this?

I'm trying to replace characters from the following map: const map<char, vector<char>> ass, note I have this string pasand I want to replace all (map value) vector chars to the Corresponding map key, I tried to iterate the map with a for cycle like this: (I got this code from another question on stackoverflow)
for (auto const &ent1 : ass) {
//ent1.first = first key
//ent1.second = second key
}
So I tried to iterate the map value vector like this:
string char1;
string char2;
string wr;
for (auto const &ent1 : ass) {
for (int i = 0; i < ent1.second.size(); i++) {
specialValues += ent1.second[i];
char2 = ent1.second[i];
char1 = ent1.first;
regex e("([" + char1 + "])");
cout << ("([" + char1 + "])");
cout << char2;
wr = regex_replace("c1a0", e, char2);
}
}
So I want the string "c1a0" to become "ciao" after the loops, but it just doesn't change anything,
I also tried:
wr = regex_replace("c1a0", e, "o");
output : c1a0
regex e("([0])");
wr = regex_replace("c1a0", e, char2);
output : c1a2
I don't know, it makes no sense for me. I don't understand, can you help me figure out what's wrong in my code?
Of course if I write:
regex e("([0])");
wr = regex_replace("c1a0", e, "o");
It gives me "c1ao" that's what I want.
Following code works for me:
#include <string>
#include <map>
#include <regex>
#include <iostream>
using namespace std;
int main() {
const map<char, vector<char>> ass = {
{ '1', {'i'} },
{ '0', {'o'} },
};
string char1;
string char2;
string wr = "c1a0";
for (auto const &ent1 : ass) {
for (int i = 0; i < ent1.second.size(); i++) {
//specialValues += ent1.second[i];
char2 = ent1.second[i];
char1 = ent1.first;
regex e("([" + char1 + "])");
cout << ("([" + char1 + "])") << std::endl;
cout << char2<< std::endl;
wr = regex_replace(wr, e, char2);
cout << wr << std::endl;
}
}
}
But IMHO, regex here is overkill. You can iterate over string manually and replace character like in the following snippet:
#include <string>
#include <set>
#include <iostream>
#include <vector>
using namespace std;
struct replace_entry {
char with;
std::set<char> what;
};
int main() {
const std::vector<replace_entry> replaceTable = {
{ 'i', {'1'} },
{ 'o', {'0'} },
};
string input = "c1a0";
for (auto const &replaceItem : replaceTable) {
for (char& c: input ) {
if(replaceItem.what.end() != replaceItem.what.find(c)) {
c = replaceItem.with;
}
}
}
cout << input << std::endl;
}
Yet another approach is to create 256 elements array of chars
#include <string>
#include <iostream>
class ReplaceTable {
private:
char replaceTable_[256];
public:
constexpr ReplaceTable() noexcept
: replaceTable_()
{
replaceTable_['0'] = 'o';
replaceTable_['1'] = 'i';
}
constexpr char operator[](char what) const noexcept {
return replaceTable_[what];
}
};
// One time initialization
ReplaceTable g_ReplaceTable;
int main() {
std::string input = "c1a0";
// Main loop
for (char& c: input ) {
if(0 != g_ReplaceTable[c] ) c = g_ReplaceTable[c];
}
std::cout << input << std::endl;
}

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