Substring of char[] in c++ - c++

I have
char t[200];
cin.get(s, 200);
int i = 5;
int j = 10;
Is there any simple way to get substriing(i,j) from t beside copying every element seperately to the another array? No strings etc. just char t[200].

If you are allowed to modify t, you could set t[j] to 0 and then use t + i to get the substring.
If not, you are going to have to make a copy.
That said, why can't you just use std::string and save yourself the headache?

char* substr(char* arr, int begin, int len)
{
char* res = new char[len + 1];
for (int i = 0; i < len; i++)
res[i] = *(arr + begin + i);
res[len] = 0;
return res;
}

If you need only to read the data then t+i is what you want, alas you'll have to manage the length of your substring...
char *sub = t+i;
int len = j-i;
printf("%.*s\n",len,sub);
If you need to have a distinct copy of the substring, then you must copy.

This should work fine:
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
char t[200];
cin.get(t, 200);
int i = 5;
int j = 10;
char *to = (char*) malloc(j-i+1);
strncpy(to, t+i, j-i);
to[j-i]='\0';
cout << to;
}
You can use new instead of malloc like this:
char* to = new char[j-i+1];

This does not do any bounds checking to ensure the destination array is large enough
char newt[200];
// copy j-i chars from position t+i to newt array
strncpy(newt, t + i, j-i);
// now null terminate
newt[j-i] = 0;

Use two pointers to denote a range within the string.
char const * beg = t+i;
char const * end = t+j+1;
std::cout.write(beg, end-beg);
Or you can use a class that encapsulates this idea. There is something like that being proposed for the standard library. In the meantime, you can write your own, or you can use one from a library. For example, llvm::StringRef.
llvm::StringRef sref(t+i, j+1-i);
std:cout << sref;

Related

Error: Initialization with '{...}' expected for aggregate object

below is my code which processes the payload[] array and store it's result on myFinalShellcode[] array.
#include <windows.h>
#include <stdio.h>
unsigned char payload[] = { 0xf0,0xe8,0xc8,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31 };
constexpr int length = 891;
constexpr int number_of_chunks = 5;
constexpr int chunk_size = length / number_of_chunks;
constexpr int remaining_bytes = length % number_of_chunks;
constexpr int size_after = length * 2;
unsigned char* restore_original(unsigned char* high_ent_payload)
{
constexpr int payload_size = (size_after + 1) / 2;
unsigned char low_entropy_payload_holder[size_after] = { 0 };
memcpy_s(low_entropy_payload_holder, sizeof low_entropy_payload_holder, high_ent_payload, size_after);
unsigned char restored_payload[payload_size] = { 0 };
int offset_payload_after = 0;
int offset_payload = 0;
for (size_t i = 0; i < number_of_chunks; i++)
{
for (size_t j = 0; j < chunk_size; j++)
{
restored_payload[offset_payload] = low_entropy_payload_holder[offset_payload_after];
offset_payload_after++;
offset_payload++;
}
for (size_t k = 0; k < chunk_size; k++)
{
offset_payload_after++;
}
}
if (remaining_bytes)
{
for (size_t i = 0; i < sizeof remaining_bytes; i++)
{
restored_payload[offset_payload++] = high_ent_payload[offset_payload_after++];
}
}
return restored_payload;
}
int main() {
unsigned char shellcode[] = restore_original(payload);
}
I get the following error on the last code line (inside main function):
Error: Initialization with '{...}' expected for aggregate object
I tried to change anything on the array itself (seems like they might be the problem). I would highly appreciate your help as this is a part of my personal research :)
In order to initialize an array defined with [], you must supply a list of values enclosed with {}, exactly as the error message says.
E.g.:
unsigned char shellcode[] = {1,2,3};
You can change shellcode to be a pointer if you want to assign it the output from restore_original:
unsigned char* shellcode = restore_original(payload);
Update:
As you can see in #heapunderrun's comment, there is another problem in your code. restore_original returns a pointer to a local variable, which is not valid when the function returns (a dangling pointer).
In order to fix this, restore_original should allocate memory on the heap using new. This allocation has to be freed eventually, when you are done with shellcode.
However - although you can make it work this way, I highly recomend you to use std::vector for dynamic arrays allocated on the heap. It will save you the need to manually manage the memory allocations/deallocations, as well as other advantages.
You can't assign a char * to a char []. You can probably do something with constexpr but I'm suspecting an XY problem here.

Generate random char/digit

I`m trying to found fastest way to generate random digit/char array.
char *randomGet(int num) {
srand(time(NULL));
const char ab[37] = { "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ" };//Alphabet&Digit
char *targ = new char[num];
for (int i = 0; i < num; i++) {
strcat(targ, ab[rand() % 38]);
}
return targ;
}
So far I've come up with this, but it does not work (argument of type char is incompatible with parameter of type const char *).
Help me find the best solution to my problem. Ty.
strcat() takes a char* as input, but you are giving it a single char instead, thus the compiler error.
Also, the buffer that strcat() writes to must be null terminated, but your targ buffer is not null terminated initially, and you are not allocating enough space for a final null terminator anyway.
You don't need to use strcat() at all. Since you are looping anyway, just use the loop counter as the index where to write in the buffer:
Also, you are using the wrong integer value when modulo the return value of rand(). You are producing a random index that may go out of bounds of your ab[] array.
Try this instead:
char *randomGet(int num)
{
srand(time(NULL));
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ"; //Alphabet&Digit
char *targ = new char[num+1];
for (int i = 0; i < num; ++i) {
targ[i] = ab[rand() % 36];
}
targ[num] = '\0';
return targ;
}
I'd make two changes. First, make the internal source array static:
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
Note that this version does not specify the array size; the compiler will figure it out from the initializer.
Second, pass in a pointer to the target array:
void randomGet(char* targ, int num) {
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
for (int i = 0; i < num - 1; ++i)
targ[i] = ab[rand() % (sizeof ab - 1)];
targ[num - 1] = '\0';
}
This way, the caller decides how to allocate memory for the string.

Parsing a string down into an array of c_strings

I wrote some code in order to turn a string (read in with getline()) into an array of c_strings. The problem I'm having is that the items I'm reading is not being stored in the array properly. I originally parsed the input based on the number of spaces in between them, and then going on from there, but that also got me the same problem. So I changed my parsing into what's below me, and I'm getting the same exact problem, suggesting to me that my parsing works, but somewhere in the process of reading what's parsed into the char* array, something is going wrong.
My code:
int i = 0;
unsigned inputSize = input.size();
unsigned int prev = 0; //prev as in previous space position
while((prev = input.find(' ', prev)) < inputSize) {
++i; ++prev;
}
char* charArray[i + 2];
memset(charArray, '\0', i + 2);
stringstream ss(input);
string buffer;
for(int a = 0; ss >> buffer; ++a) {
charArray[a] = const_cast<char*>(buffer.c_str());
}
What I'm doing is that I'm counting the number of spaces of my input, and making a char* array of that number + 2 (+2 because I need to end it with NULL). After that, I parse my input and read it into the array. I am using ss >> buffer as my termination clause because I will not end up allocating memory outside the allocated memory for charArray. buffer.c_str gets me a const char*, so I const_cast it in order for me to store it into the (non-const) array of char*. I use memset to set all elements to NULL because I know it'll be written over, except the last element, which I want to remain NULL.
Test:
Input: Why hello world
Output: Junk
What's going wrong inside my program?
The pointer returned by buffer.c_str() is valid only as long as the string stored in buffer is not modified. If you need to modify buffer, you have to copy its contents beforehand, if you need the old content later on.
See Right way to split an std::string into a vector [duplicate].
Live Example
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
std::string input = "Why hello world";
std::stringstream ss(input);
std::vector<std::string> vstrings(std::istream_iterator<std::string>(ss),
std::istream_iterator<std::string>{}); // C++11 brace syntax
char** charArray = new char*[vstrings.size()];
for (unsigned int i = 0; i < vstrings.size(); i++)
charArray[i] = (char*)vstrings[i].c_str();
for (unsigned int i = 0; i < vstrings.size(); i++)
std::cout << charArray[i] << "\n";
delete[] charArray;
}

Get string content from string pointer C++

so I'm working on a project that I have to read contents from a file and then analyze them. But I'm having a problem with getting the string out of a pointer that contains the address to what I need.
string lePapel(vector<char> vec){
string *str, s;
int i, j = 0;
vector<char> aux;
aux.resize(6);
for (i = 57; i <= 62; i++){
aux[j] = vec[i];
j++;
}
str = new string[aux.size()];
for (i = 0; i < 6; i++){ str[i] = aux[i]; }
return s;
}
So, the file contains in the array positions from 57 to 62 the word: ABCB4, but when returning the string s my output is A only as expected because of the pointer.
The thing is that I have been trying to find a solution and storing the whole content from vec[57] to vec[64] into the string s and returning it, and the closest that I got to returning anything plausible was using a pointer.
So, now to my question, how can I iterate the *str pointer and copy the whole content to s and return it?
Thanks in advance
I'd suggest you to not use pointers on string in your case. The following code is probably what you want :
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string lePapel(vector<char> vec){
int j = 0;
vector<char> aux;
aux.resize(6);
for (int i = 57; i <= 62; i++){
aux[j] = vec[j];
j++;
}
string str;
str.reserve(6);
for (int i = 0; i < 6; i++){ str.push_back(aux[i]); }
return str;
}
int main() {
char x[5] = {'A', 'B', 'C', 'B', '4'};
vector<char> vec(x, x + 5);
string s = lePapel(vec);
cout << s;
return 0;
}
Tested here : Tested code
About reserving space to your vector : c++ vector::reserve
Same for strings : reserve for strings
The dynamic array of string objects and the whole aux vector seem completely needless here (unless there's some other purpose for them in your code). Additionally, str is currently causing a memory leak because you never delete it when you're finished.
A much simpler approach is just to append the characters one-at-a-time to the s string object (assuming it's a std::string):
string lePapel(vector<char> vec) {
string s;
for (int i = 57; i <= 62; i++) {
s += vec[i];
}
return s;
}
There are various ways to make the code even shorter (and more efficient) than that though, if you really want to.
EDIT: If you still need/want to iterate your dynamic array and concatenate the contents into s, here's how you could do it:
for (i = 0; i < 6; i++) s += str[i];
delete [] str; //<-- very important!
Short answer, you don't want a string * you want a char *. What you created is a string array. String objects contain a pointer to the char * data you are trying to capture. Also, the sizeof(std::string) (8 bytes in size) is a lot bigger than sizeof(char) (1 byte in size) the second character you store is 8 bytes away from the first character instead of being adjacent.
There are a lot of other C++ style and safety concerns, but I'll stick with the question. ;)

Flaws in algorithm and algorithm performance

char *stringmult(int n)
{
char *x = "hello ";
for (int i=0; i<n; ++i)
{
char *y = new char[strlen(x) * 2];
strcpy(y,x);
strcat(y,x);
delete[] x;
x=y;
}
return x;
}
I'm trying to figure out what the flaws of this segment is. For one, it deletes x and then tries to copy it's values over to y. Another is that y is twice the size of x and that y never gets deleted. Is there anything that I'm missing? And also, I need to figure out how to get algorithm performance. If you've got a quick link where you learned how, I'd appreciate it.
y needs one more byte than strlen(x) * 2 to make space for the terminating nul character -- just for starters.
Anyway, as you're returning a newed memory area, it's up to the caller to delete it (eek).
What you're missing, it seems to me, is std::string...!-)
As for performance, copying N characters with strcpy is O(N); concatenating N1 characters to a char array with a previous strlen of N2 is O(N1+N2) (std::string is faster as it keeps the length of the string in an O(1)-accessible attribute!-). So just sum N+N**2 for N up to whatever your limit of interest is (you can ignore the N+ part if all you want is a big-O estimate since it's clearly going to drop away for larger and larger values of N!-).
For starters delete[] x; operates for the first time round the loop on some static memory. Not good.
It looks like an attempt to return a buffer containing 2^n copies of the string "hello ". So the fastest way to do that would be to figure out the number of copies, then allocate a big enough buffer for the whole result, then fill it with the content and return it.
void repeat_string(const std::string &str, int count, std::vector<char> &result)
{
result.resize(str.size() * count);
for (int n = 0; n < count; n++)
str.copy(&result[n * s.size()], s.size());
}
void foo(int power, std::vector<char> &result)
{
repeat_string("hello ", 1 << (power + 1), result);
}
no need to call strlen() in a loop - only call it once;
when new is called no space is requested for the null-character - will cause undefined behaviour;
should use strcpy instead of strcat - you already know where to copy the second string and findig the end of string by strcat requires extra computation;
delete[] is used on a statically allocated string literal - will cause undefined behaviour;
memory is constantly reallocated although you know the result length well in advance - memory reallocation is quite expensive
You should instead compute the result length at once and allocate memory at once and pass the char* as an in-parameter:
char* stringMult(const char* what, int n)
{
const size_t sourceLen = strlen( what );
int i;
size_t resultLen = sourceLen;
// this computation can be done more cleverly and faster
for( i = 0; i < n; i++ ) {
resultLen *= 2;
}
const int numberOfCopies = resultLen / sourceLen;
char* result = new char[resultLen + 1];
char* whereToWrite = result;
for( i = 0; i < numberOfCopies; i++ ) {
strcpy( whereToWrite, what );
whereToWrite += sourceLen;
}
return result;
}
Certain parts of my implementation can be optimized but still it is much better and (I hope) contains no undefined-behaviour class errors.
you have to add one while allocating space for Y for NULL terminating string
Check the code at below location http://codepad.org/tkGhuUDn
char * stringmult (int n)
{
int i;
size_t m;
for (i = 0, m = 1; i < n; ++i; m *= 2);
char * source = "hello ";
int source_len = strlen(source);
char * target = malloc(source_len*m+1) * sizeof(char));
char * tmp = target;
for (i = 0; i < m; ++i) {
strcpy(tmp, source);
tmp += source_len;
}
*tmp = '\0';
return target;
}
Here a better version in plain C. Most of the drawbacks of your code have been eliminated, i.e. deleting a non-allocated pointer, too many uses of strlen and new.
Nonetheless, my version may imply the same memory leak as your version, as the caller is responsible to free the string afterwards.
Edit: corrected my code, thanks to sharptooth.
char* string_mult(int n)
{
const char* x = "hello ";
char* y;
int i;
for (i = 0; i < n; i++)
{
if ( i == 0)
{
y = (char*) malloc(strlen(x)*sizeof(char));
strcpy(y, x);
}
else
{
y = (char*)realloc(y, strlen(x)*(i+1));
strcat(y, x);
}
}
return y;
}
Nobody is going to point out that "y" is in fact being deleted?
Not even one reference to Schlmeiel the Painter?
But the first thing I'd do with this algorithm is:
int l = strlen(x);
int log2l = 0;
int log2n = 0;
int ncopy = n;
while (log2l++, l >>= 1);
while (log2n++, n >>= 1);
if (log2l+log2n >= 8*(sizeof(void*)-1)) {
cout << "don't even bother trying, you'll run out of virtual memory first";
}