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

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++.

Related

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 concatenate additional character to a string in 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

Data loss issue while converting the string from std::string to const char *

In this function, passing string as an argument (which is having the huge amount of data as a string)...
SendBytes method is defined like this
bool NetOutputBuffer_c::SendBytes ( const void * pBuf, int iLen )
{
BYTE * pMy = (BYTE*)pBuf;
while ( iLen>0 && !m_bError )
{
int iLeft = m_iBufferSize - ( m_pBufferPtr-m_pBuffer );
if ( iLen<=iLeft )
{
printf("iLen is %d\n",iLen);
memcpy ( m_pBufferPtr, pMy, iLen );
m_pBufferPtr += iLen;
break;
}
ResizeIf ( iLen );
}
return !m_bError;
}
bool NetOutputBuffer_c::SendCompressedString ( std::string sStr )
{
std::cout << sStr << endl;
const char *cStr = sStr.c_str();
std::cout << cStr <<endl;
int iLen = cStr ? strlen(cStr) : 0;
SendInt ( iLen );
return SendBytes ( cStr, iLen );
}
Tried printing the value of sStr to check whether it has proper data or not.
Then converting the std::string to const char *
After converting it,tried printing the value of cStr. But it(cStr) actually contains 5% of the actual data(sStr)...
what shall I need to do in order to get the whole data?
Can someone guide me in this regard?
strlen works for c-strings. That is, null terminated strings. It searches for a '\0' character, and returns that character's position as the length of the string. You have compressed binary data, not a c-string. It almost certainly contains a 0 before the end of the string. Use sStr.size() instead.
SendInt ( sStr.size() );
return SendBytes ( sStr.c_str(), sStr.size() );

How to construct a CString/std::string from a string position

Given the following:
for( std::string line; getline( input, line ); )
{
CString strFind = line.c_str();
int n = strFind.ReverseFind( '\\' );
CString s = CString( strFind,n );
cout << s << endl;
// m_Path.push_back( line.c_str() );
}
It is reading a .ini configuration and on this .ini I have a line:
C:\Downloads\Insanity\Program\7. World.exe
this line is added to the vector<CString>.
My problem isint n = strFind.ReverseFind( '\\\' ); finds the string pos of the first \ searching from the end of the string to the beginning, after when constructing a CString like this CString s = CString( strFind,n ); I'm constructing the FIRST n characters on the string so s is equal C:\Downloads\Insanity\Program but what I want is to copy 7 .World.exe to the CString s and not the other way, how can I do that using CString or std::string?
Are you converting the std::string to a CString only for the ReverseFind functionality? If so, you can use std::basic_string::find_last_of instead.
#include <iostream>
#include <string>
int main()
{
std::string s(R"(C:\Downloads\Insanity\Program\7. World.exe)");
auto pos = s.find_last_of( '\\' ) + 1; //advance to one beyond the backslash
std::string filename( s, pos );
std::cout << filename << std::endl;
}
How about:
CString s = strFind.Mid(n+1);
or:
std::string s = line.substr(n+1);

c++ Dont work cycle

i transform char* to char**. Each word must fold to array. But fold only first word.
input: "abc def 123"
out (expected): num ==3,arr == {"abc","def","123"}
out(real): num == 1,arr == {"abc"}
struct CommandArray
{
vector<char*> Arr;
USHORT Num;
};
CommandArray Text::StrToArray(LPSTR Str)
{
CommandArray Out;
LPSTR TempStr;
Out.Num = 0;
TempStr = strtok (Str," ");
while(TempStr != NULL)
{
Out.Arr.push_back(TempStr);
Out.Num++;
TempStr = strtok(NULL," ");
}
return Out;
}
strtok modifies its first argument (that's why it is a char* and not a char const*). One guess is that you do the same after the call to Text::StrToArray.
First. Use cin.getline(input,32); to get an input seperated by spaces, cin>>input won't work.
Concerning char* to char**. The code below folds each word into an array.
#include<windows.h>
#include<vector>
#include<string>
#include<iostream>
using namespace std;
struct CommandArray
{
vector<char*> Arr;
USHORT Num;
};
CommandArray StrToArray(LPSTR Str)
{
CommandArray Out;
LPSTR TempStr;
Out.Num = 0;
TempStr = strtok (Str," ");
while(TempStr != NULL)
{
Out.Arr.push_back(TempStr);
Out.Num++;
TempStr = strtok(NULL," ");
}
return Out;
}
int main()
{
int ROWS=80; //80 characters wide
int COLUMNS=20;// 20 lines
int i;
char seperators[] = " ,\t\n";
char *token;
char* input_Dynamic1DCharPointerArray = new char[80];
char **output_Dynamic2DCharPointerArray = 0;
//memory allocated for elements of rows.
output_Dynamic2DCharPointerArray = new char *[ROWS] ;
//memory allocated for elements of each column.
for( i = 0 ; i < ROWS ; i++ ) output_Dynamic2DCharPointerArray[i] = new char[COLUMNS];
strcpy(input_Dynamic1DCharPointerArray,"apples 123 oranges 456 bananas 789 lemons 101112" );
//cout<<" \n";
//cin.getline(input_Dynamic1DCharPointerArray,32);
cout<<" \ninput = "<<input_Dynamic1DCharPointerArray<<" \n\n";
cout<<"Output = \n";
token = strtok( input_Dynamic1DCharPointerArray, seperators );
i=0;
while( token != NULL )
{
strcpy(output_Dynamic2DCharPointerArray[i],token);
cout<<output_Dynamic2DCharPointerArray[i]<<" \n";
token = strtok( NULL, seperators ); // C4996
i++;
}
cout<<" \n";
delete[] input_Dynamic1DCharPointerArray;
//free the allocated memory
for( i = 0 ; i < ROWS ; i++ )
delete [] output_Dynamic2DCharPointerArray[i] ;
delete [] output_Dynamic2DCharPointerArray ;
return 0;
}