Skip to content

Instantly share code, notes, and snippets.

@ktprezes
Last active August 22, 2024 14:14
Show Gist options
  • Save ktprezes/4a591556b0e60b1b386646f88a867407 to your computer and use it in GitHub Desktop.
Save ktprezes/4a591556b0e60b1b386646f88a867407 to your computer and use it in GitHub Desktop.
C++ - returns copy of passed `src` string with `sep` separators inserted every `group_len` characters counting from left-to-rigth or right-to-left, depending on the `right_to_left` bool param. May be used for example to insert 'thousand separators' into string representations of large numbers. This version has plenty of debugging messages.
#include <format>
#include <iostream>
using namespace std;
/**
* @brief inserts into the `src` string, every `group_len` characters, the `sep` string; depending on the
* `right_to_left` parameter starts counting characters from left (when =false) or from right (when =true)
* It does NOT change the original string passed as an argument
* @param src source string the separators are to be inserted into
* @param sep separators to be inserted into the `src` string
* @param group_len the `sep` string will be inserted into `src` string every `group_len` characters
* @param right_to_left when =false starts counting characters from left, when =true starts counting from right
* @return modified copy of `src` string with `sep` separators inserted every `group_len` chars counting l2r or r2l
*/
string insertSeparators(
const string &src,
const string &sep,
const unsigned int group_len,
const bool right_to_left = false
) {
cout << "\tInside Params: src: " << src << " sep: " << sep << " group len: " << group_len <<
" from right: " << right_to_left << endl;
if (src.empty() || sep.empty() || group_len == 0 || src.length() <= group_len) { return src; }
cout << "\tInside: " << &src << " " << src << " - src passed seen inside" << endl;
const auto len_remainder = src.length() % group_len;
auto position = src.length() -
((right_to_left || len_remainder == 0) ? group_len : len_remainder);
std::string s = src;
cout << "\tInside: " << &s << " " << s << " - s declared inside" << endl;
for (; position > group_len; position -= group_len) {
s.insert(position, sep);
cout << "\tInside: " << &s << " " << s << " - s after sep insertion" << endl;
}
s.insert(position, sep);
cout << "\tInside: " << &s << " " << s << " - s after sep insertion" << endl;
return s;
} // string insertSeparators( … )
int main() {
const std::string s = "Hello World!";
cout << endl << "String and their addresses:" << endl << endl;
cout << "OUTSIDE: " << &s << ", " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() <<" - original string s passed as arg to function" << endl << endl;
std::string result;
result = insertSeparators(s, "", 4, true);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
result = insertSeparators(s, "_", 4, true);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
result = insertSeparators(s, "_*_", 4, false);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
result = insertSeparators(s, "_viv_", 3, true);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
result = insertSeparators(s, "_", 11, false);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
result = insertSeparators(s, "_", 11, true);
cout << "OUTSIDE: " << &result << " " << result << ", len: "<< result.length()<< ", capacity: "<< result.capacity() << " - string returned from function" << endl;
cout << "OUTSIDE: " << &s << " " << s << ", len: "<< s.length()<< ", capacity: "<< s.capacity() << " - original string s after function" << endl << endl;
return 0;
} // int main()
/*
// sample output of above code:
// The debugging messages show by the way how many strings are created (3 of them actually),
// and string memory management - one of them increases its capacity, when needed.
Strings and their addresses:
OUTSIDE: 0x818c3ffb00, Hello World!, len: 12, capacity: 15 - original string s passed as arg to function
Inside Params: src: Hello World! sep: group len: 4 from right: 1
OUTSIDE: 0x818c3ffb20 Hello World!, len: 12, capacity: 15 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Inside Params: src: Hello World! sep: _ group len: 4 from right: 1
Inside: 0x818c3ffb00 Hello World! - src passed seen inside
Inside: 0x818c3ffa50 Hello World! - s declared inside
Inside: 0x818c3ffa50 Hello Wo_rld! - s after sep insertion
Inside: 0x818c3ffa50 Hell_o Wo_rld! - s after sep insertion
OUTSIDE: 0x818c3ffb20 Hell_o Wo_rld!, len: 14, capacity: 15 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Inside Params: src: Hello World! sep: _*_ group len: 4 from right: 0
Inside: 0x818c3ffb00 Hello World! - src passed seen inside
Inside: 0x818c3ffa50 Hello World! - s declared inside
Inside: 0x818c3ffa50 Hello Wo_*_rld! - s after sep insertion
Inside: 0x818c3ffa50 Hell_*_o Wo_*_rld! - s after sep insertion
OUTSIDE: 0x818c3ffb20 Hell_*_o Wo_*_rld!, len: 18, capacity: 30 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Inside Params: src: Hello World! sep: _viv_ group len: 3 from right: 1
Inside: 0x818c3ffb00 Hello World! - src passed seen inside
Inside: 0x818c3ffa50 Hello World! - s declared inside
Inside: 0x818c3ffa50 Hello Wor_viv_ld! - s after sep insertion
Inside: 0x818c3ffa50 Hello _viv_Wor_viv_ld! - s after sep insertion
Inside: 0x818c3ffa50 Hel_viv_lo _viv_Wor_viv_ld! - s after sep insertion
OUTSIDE: 0x818c3ffb20 Hel_viv_lo _viv_Wor_viv_ld!, len: 27, capacity: 30 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Inside Params: src: Hello World! sep: _ group len: 11 from right: 0
Inside: 0x818c3ffb00 Hello World! - src passed seen inside
Inside: 0x818c3ffa50 Hello World! - s declared inside
Inside: 0x818c3ffa50 Hello World_! - s after sep insertion
OUTSIDE: 0x818c3ffb20 Hello World_!, len: 13, capacity: 30 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Inside Params: src: Hello World! sep: _ group len: 11 from right: 1
Inside: 0x818c3ffb00 Hello World! - src passed seen inside
Inside: 0x818c3ffa50 Hello World! - s declared inside
Inside: 0x818c3ffa50 H_ello World! - s after sep insertion
OUTSIDE: 0x818c3ffb20 H_ello World!, len: 13, capacity: 30 - string returned from function
OUTSIDE: 0x818c3ffb00 Hello World!, len: 12, capacity: 15 - original string s after function
Process finished with exit code 0
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment