How to concatenate additional character to a string in c++ - c++

Suppose there is a array..and the contents of the array="ironman" Now, i need to add some additional character to this string like "i*r%o#n#m^a!n"
out[i]="ironman"
Outputs:
out[]=i
out[]=*
out[]=r
out[]=%
out[]=o
out[]=#
out[]=n
out[]=#
out[]=m
out[]=^
out[]=a
out[]=!
out[]=n
I have written a code which concatenate at the end of the string, but i want to concatenate between the string.
char in[20] = "ironman";
const unsigned int symbol_size = 5;
std::string symbols[symbol_size];
std::string out(in);
out = out + "#" + "*" + "#";

You can use string.insert(pos, newString). Example below:
std::string mystr
mystr.insert(6,str2);
If you know the index, specify it directly as 'pos'. Otherwise, you may want to do somekind of str.find() and pass in the result.

If I have understood correctly what you need then you can use the following straightforward approach
#include <iostream>
#include <string>
#include <cstring>
int main()
{
char in[] = "ironman";
char symbols[] = "*%##^!";
std::string s;
s.reserve( std::strlen( in ) + std::strlen( symbols ) );
char *p = in;
char *q = symbols;
while ( *p && *q )
{
s.push_back( *p++ );
s.push_back( *q++ );
}
while ( *p ) s.push_back( *p++ );
while ( *q ) s.push_back( *q++ );
std::cout << s << std::endl;
}
The program output is
i*r%o#n#m^a!n
You can write a separate function. For example
#include <iostream>
#include <string>
#include <cstring>
std::string interchange_merge( const char *s1, const char *s2 )
{
std::string result;
result.reserve( std::strlen( s1 ) + std::strlen( s2 ) );
while ( *s1 && *s2 )
{
result.push_back( *s1++ );
result.push_back( *s2++ );
}
while ( *s1 ) result.push_back( *s1++ );
while ( *s2 ) result.push_back( *s2++ );
return result;
}
int main()
{
char in[] = "ironman";
char symbols[] = "*%##^!";
std::string s = interchange_merge( in, symbols );
std::cout << s << std::endl;
}
The output will be the same as above
i*r%o#n#m^a!n

Related

Path string from std::vector`

I have a vector of char which looks something like
C:/Users/person/Desktop/Albedo.pngC:/Users/person/Desktop/Metallic.pngC:/Users/person/Desktop/Noice.pngC:/Users/person/Desktop/AO.png
How do I split the vector to individual paths?
That is, I want to have
std::string path1; // = C:/Users/person/Desktop/Albedo.png;
std::string path2; // = C:/Users/person/Desktop/Metallic.png;
std::string path3; // = C:/Users/person/Desktop/Noice.png;
std::string path4; // = C:/Users/person/Desktop/AO.png;
Any idea how can I do that?
Thanks in advance!
For example a straightforward approach provided that each path in the vector has the extension .png can look for example the following way as it is shown in the demonstrative program below.
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cstring>
int main()
{
const char *s ="C:/Users/person/Desktop/Albedo.png"
"C:/Users/person/Desktop/Metallic.png"
"C:/Users/person/Desktop/Noice.png"
"C:/Users/person/Desktop/AO.png";
std::vector<char> v( s, s + std::strlen( s ) );
std::vector<std::string> paths;
const char *ext = ".png";
size_t n = std::strlen( ext );
for ( auto first = std::begin( v ), last = std::end( v ), it = first;
( it = std::search( first, last, ext, ext + n ) ) != last;
first = it
)
{
std::advance( it, n );
paths.push_back( { first, it } );
}
for ( const auto &path : paths )
{
std::cout << path << '\n';
}
return 0;
}
The program output is
C:/Users/person/Desktop/Albedo.png
C:/Users/person/Desktop/Metallic.png
C:/Users/person/Desktop/Noice.png
C:/Users/person/Desktop/AO.png

Converting chars into ASCII returns numbers too big

So I have this function that XORes a string and then it turns it into a format like this:
\x55\x1\x53\x21...
But the problem is that the function firstly returned negative values, but I fixed that by making it from a CHAR into a UCHAR, but now it starts giving me values that are too big and the compiler doesn't let me compile because of it. Any thoughts of why this would happen? Couldn't find anything about it online.
__inline char* EncryptString(const char* String, const char* Key)
{
char* szEncrypted = new char[lstrlenA(String) + 1];
memcpy(szEncrypted, String, lstrlenA(String) + 1);
for (int32_t i = 0; i < lstrlenA(String); ++i)
szEncrypted[i] = String[i] ^ Key[i % (lstrlenA(Key))];
std::stringstream lpStream;
for (int32_t i = 0; i < lstrlenA(szEncrypted); ++i)
{
char cCharInd = szEncrypted[i];
UINT nCharNum = UINT(cCharInd);
lpStream << "\\x" << std::hex << nCharNum;
}
std::string sHexEscaped = lpStream.str();
lpStream.clear();
delete[] szEncrypted;
char* szReturn = new char[sHexEscaped.length() + 1];
memcpy(szReturn, sHexEscaped.c_str(), sHexEscaped.length() + 1);
return szReturn;
}
The problem is the type char can be signed or unsinged (depends on compiler). I think the following code helps you:
const unsigned char uc = static_cast<unsigned char>( szEncrypted[i] );
const unsigned int code = uc;
lpStream << "\\x" << std::hex << code;
P.S. Looks like you actually don't need to use temporary buffer szEncrypted.
UPDATE:
I tried to demonstrate how such encryption may works in code below (the source file encoding is Windows-1251). You also have to know that encrypted string may contain \0 bytes, so, to calculate the length of encrypted string you would probably use something like this: const char rawString[] = "\xf\x55\x0\x1e\x22\x98\x20\x1e\x2b\x4b\x12"; const int rawSize = sizeof( raw ) - 1;
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
string EncryptString( const char* String, const char* Key )
{
std::stringstream lpStream;
const int keyLength = strlen( Key );
for( int i = 0; String[i] != '\0'; i++ ) {
char ec = String[i] ^ Key[i % keyLength];
unsigned char uc = static_cast<unsigned char>( ec );
lpStream << "\\x" << std::hex << static_cast<unsigned int>( uc );
}
return lpStream.str();
}
void DecryptString( string& String, const char* Key )
{
const int keyLength = strlen( Key );
for( string::size_type i = 0; i < String.length(); i++ ) {
String[i] ^= Key[i % keyLength];
}
}
int main()
{
system( "ChCp 1251" );
const char* key = "Пётр";
cout << EncryptString( "Антон Тодуа", key ) << endl;
const char raw[] = "\xf\x55\x0\x1e\x22\x98\x20\x1e\x2b\x4b\x12";
string data( raw, sizeof( raw ) - 1 );
DecryptString( data, key );
cout << data << endl;
return 0;
}

How to sort each character string of character string array

I want to sort each string of array of strings , here is my code that i tried.
#include <iostream>
#include <algorithm>
void _sort_word(char *str)
{
int len = strlen(str);
std::sort(str,str+len); // program get stuck here.
}
int main()
{
char *str[] = {"hello", "world"};
for(int i=0;i<2;i++){
_sort_word(str[i]);
cout << str[i] << "\n";
}
}
I want to know is sort(str,str+len); a valid statement here, if not what should be done instead ?
First of all string literals in C++ have types of constant character arrays. So the correct array declaration will look like
const char *str[] = {"hello", "world"};
^^^^^
Thus the string literals pointed to by the elements of the array are immutable.
You should declare at least a two dimensional array.
Here is a demonstrative program
#include <iostream>
#include <algorithm>
#include <cstring>
void sort_word( char *s )
{
size_t l = std::strlen( s );
std::sort( s, s + l );
}
int main()
{
char str[][6] = { "hello", "world" };
for ( auto &s : str ) sort_word( s );
for ( auto &s : str ) std::cout << s << std::endl;
return 0;
}
Its output is
ehllo
dlorw
If your compiler does not support the range based for statement then you can write instead
for ( size_t i = 0; i < sizeof( str ) / sizeof( *str ); i++ ) sort_word( str[i] );

After compiling the code it crashes (couldn't get why)

When i am using StrSplit function with a constant string it works great. but when i read the line from a file and then use it as string for StrSplit function my program crashes. the following is the code and the error screen shot.
string Read_from_file(){
//load the text file and put it into a single string:
std::ifstream in("test.txt");
std::stringstream buffer;
buffer << in.rdbuf();
std::string test = buffer.str();
std::cout << test << std::endl << std::endl;
return test;
}
// split the given string according to give delimeters
vector<string> &StrSplit( string inStr, string sepStr, vector<string> &outStrVec) {
char * comp;
char * buffer = new char[ strlen( inStr.c_str() ) ];
strcpy( buffer, inStr.c_str() );
comp = strtok ( buffer, sepStr.c_str() );
while ( comp != NULL ) {
outStrVec.push_back(comp);
comp = strtok ( NULL, sepStr.c_str() );
}
delete[] comp;
delete[] buffer;
return outStrVec;
}
vector<string> StrSplit( string inStr, string sepStr ) {
vector<string> outStrVec;
return StrSplit( inStr, sepStr, outStrVec );
![enter image description here][2]}
int main( ) {
Read_from_file();
string fileinput = Read_from_file();
vector<string> v;
string inStr = fileinput;
v = StrSplit( inStr, "|#$ *#.&\"!^01" );
for (unsigned int i = 0; i < v.size(); ++i) {
cout << v[i] << '\n';
}
}
The buffer is too small to contain the string including the terminating 0 character.
Change
char * buffer = new char[ strlen( inStr.c_str() ) ];
to
char * buffer = new char[ strlen( inStr.c_str() ) + 1];
And don't call delete on pointers you didn't new (remove delete[] comp).
Actually, I would never use strtok in C++.

Reading lines from a binary file C++

I am trying to read a binary file and store it into a database, however I get a segmentation fault when I try to store a string type into the database. To be exact, the error occurs inside the push function:
new_node->name = name;
I can't seem to find a good solution on the web, and I'm aimlessly trying different things... any help would be appreciated.
//
// loadbin.cpp
//
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
#include "studentsDB.h"
int main( int argc, char* argv[] ) {
string name;
string id;
int numCourses;
int crn;
vector<int> crns;
studentsDB sDB;
studentsDB::node *students = 0;
int in = 1;
if( argc > 1 ) {
ifstream infile(argv[in], ios::binary );
while( !infile.eof() ) {
infile.read( ( char* )(name.c_str()), sizeof( string ) );
infile.read( ( char* )(id.c_str()), sizeof( string ) );
infile.read( ( char* ) &numCourses, sizeof( int ) );
do{
crns.push_back( crn );
}
while( infile.read( ( char* ) &crn, sizeof( int ) ) );
sDB.push( &students, (string)name, (string)id, numCourses, crns );
}
//sDB.printList( students );
}
else
cout << "Not enough argument" << endl;
}
void studentsDB::push( struct node** head_ref, string name, string id,
int numCourses, vector<int>crns ) {
struct node* new_node = ( struct node* ) malloc(sizeof(struct node));
new_node->name = name;
//new_node->id = id;
new_node->numCourses = numCourses;
//new_node->crns = crns;
new_node->next = (*head_ref);
(*head_ref) = new_node;
size++;
}
This code is bad:
infile.read( ( char* )(name.c_str()), sizeof( string ) );
You can't write to the buffer returned by c_str(), it is not guaranteed to be long enough to hold your result. sizeof(string) has nothing to do with the size the string can hold, by the way. You will need to allocate your own char[] buffer to hold the results of infile.read, then convert to a string afterwards.