Okay, so I'm working on a memory editor in c++, I have a list of offsets and if I predefine what to change the offset too (0x68) then it works, but I was wondering if there was a way to convert string, as in, cin >> string, and it would split the string into bytes or char*s so it could use them in the offsets? Sorry if this doesn't make much sense.
The std::string class has two methods that can help you:
c_str(), that returns a \0-terminated char* string (AKA a "C"-style string);
data(), that returns the content of the string in a char const*, but without \0 termination; you have to retrieve the length separately with length() or size().
You can call c_str() to get a raw char array representing the string data as a c string.
You can use data() and memcpy() to copy all the bytes to another address, or access the bytes in the string by indexing the string object...
std::string x;
if (std::cin >> x) // note: read one whitespace-separated token, use getline for lines
{
memcpy(p_dest, x.data(), x.size()); // to copy everything...
// ...or...
p_dest[offset] = x[i]; // copy one character, 0 <= i < x.size()
}
Related
I have a QByteArray object with 256 bytes inside of it. However, when I try to convert it to a byte string (std::string), it comes up with a length of 0 to 256. It is very inconsistent with how long the string is, but there are always 256 bytes in the array. This data is encrypted and as such I expect a 256-character garbage output, but instead I am getting a random number of bytes.
Here is the code I used to try to convert it:
// Fills array with 256 bytes (I have tried read(256) and got the same random output)
QByteArray byteRecv = socket->read(2048);
// Gives out random garbage (not the 256-character garbage that I need)
string recv = byteRecv.constData();
The socket object is a QTcpSocket* if it's necessary to know.
Is there any way I can get an exact representation of what's in the array? I have tried converting it to a QString and using the QByteArray::toStdString() method, but neither of those worked to solve the problem.
QByteArray::constData() member function returns a raw pointer const char*. The constructor of std::string from a raw pointer
std::string(const char* s);
constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character. If s does not point to such a string, the behaviour is undefined.
Your buffer is not a null-terminated string and can contain null characters in the middle. So you should use another constructor
std::string(const char* s, std::size_type count);
that constructs the string with the first count characters of character string pointed to by s.
That is:
std::string recv(byteRecv.constData(), 256);
For a collection of raw bytes, std::vector might be a better choice. You can construct it from two pointers:
std::vector<char> recv(byteRecv.constData(), byteRecv.constData() + 256);
I'm using the XOR encryption so when I'm going to decrypt my string I need to get the length of that string.
I tried in this way:
string to_decode = "abcd\0lom";
int size = to_decode.size();
or in this way:
string to_decode = "abcd\0lom";
int size = to_decode.lenght();
Both are wrong because the string contain \0.
So how can I have the right length of my string?
The problem is with the initialisation, not with the size. If you use the constructor taking a const char *, it interprets that argument as a NUL-terminated string. So your std::string is only initialised with the string abcd.
You need to use a range-based constructor:
const char data[] = "abcd\0lom";
std::string to_decode(data, data + (sizeof data) - 1); // -1 to not include terminating NUL
[Live example]
However, be careful with such strings. While std::string can deal with embedded NULs perfectly fine, the result of c_str() will behave as "truncated" as far as all NUL-terminated APIs are concerned.
When you initialize the std::string, with a \0 in the middle, you loose all data ahead of it. If you think about it, a std::string is just a wrapper for a char*, and that gets terminated by a null termination \0. If the \0, doesn't have any meaning in the string, then you could escape it, like this:
string to_decode = "abcd\\0lom";
and the size would be 9. Otherwise, you could a container (eg: std::vector), of char's for the data storage
As others have said, the problem is that the code uses the constructor that takes const char*, and that only copies up to the \0. But, by a very strange coincidence, std::string has a constructor that can handle that case:
const char text[] = "abcd\0lom";
std::string to_decode(text, sizeof(text) - 1);
int size = to_decode.size();
The constructor will copy as many characters as you tell it to.
I'm just starting c++ and am having difficulty understanding const char*. I'm trying to convert the input in the method to string, and then change the strings to add hyphens where I want and ultimately take that string and convert it back to char* to return. So far when I try this it gives me a bus error 10.
char* getHyphen(const char* input){
string vowels [12] = {"A","E","I","O","U","Y","a","e","i","o","u","y"};
//convert char* to string
string a;
int i = 0;
while(input != '\0'){
a += input[i];
input++;
i++;
}
//convert a string to char*
return NULL;
}
A: The std::string class has a constructor that takes a char const*, so you simply create an instance to do your conversion.
B: Instances of std::string have a c_str() member function that returns a char const* that you can use to convert back to char const*.
auto my_cstr = "Hello"; // A
std::string s(my_cstr); // A
// ... modify 's' ...
auto back_to_cstr = s.c_str(); // B
First of all, you don't need all of that code to construct a std::string from the input. You can just use:
string a(input);
As far as returning a new char*, you can use:
return strdup(a.c_str()); // strdup is a non-standard function but it
// can be easily implemented if necessary.
Make sure to deallocate the returned value.
It will be better to just return a std::string so the users of your function don't have to worry about memory allocation/deallocation.
std::string getHyphen(const char* input){
Don't use char*. Use std::string, like all other here are telling you. This will eliminate all such problems.
However, for the sake of completeness and because you want to understand the background, let's analyse what is going on.
while(input != '\0'){
You probably mean:
while(*input != '\0') {
Your code compares the input pointer itself to \0, i.e. it checks for a null-pointer, which is due to the unfortunate automatic conversion from a \0 char. If you tried to compare with, say, 'x' or 'a', then you would get a compilation error instead of runtime crashes.
You want to dereference the pointer via *input to get to the char pointed to.
a += input[i];
input++;
i++;
This will also not work. You increment the input pointer, yet with [i] you advance even further. For example, if input has been incremented three times, then input[3] will be the 7th character of the original array passed into the function, not the 4th one. This eventually results in undefined behaviour when you leave the bounds of the array. Undefined behaviour can also be the "bus error 10" you mention.
Replace with:
a += *input;
input++;
i++;
(Actually, now that i is not used any longer, you can remove it altogether.)
And let me repeat it once again: Do not use char*. Use std::string.
Change your function declaration from
char* getHyphen(const char* input)
to
auto hyphenated( string const& input )
-> string
and avoid all the problems of conversion to char const* and back.
That said, you can construct a std::string from a char_const* as follows:
string( "Blah" )
and you get back a temporary char const* by using the c_str method.
Do note that the result of c_str is only valid as long as the original string instance exists and is not modified. For example, applying c_str to a local string and returning that result, yields Undefined Behavior and is not a good idea. If you absolutely must return a char* or char const*, allocate an array with new and copy the string data over with strcpy, like this: return strcpy( new char[s.length()+1], s.c_str() ), where the +1 is to accomodate a terminating zero-byte.
From what I understand cin.getLine gets the first char(which I think it a pointer) and then gets that the length. I have used it when cin for a char. I have a function that is returning a pointer to the first char in an array. Is there an equivalent to get the rest of the array into a char that I can use the entire array. I explained below what I am trying to do. The function works fine, but if it would help I could post the function.
cmd_str[0]=infile();// get the pointer from a function
cout<<"pp1>";
cout<< "test1"<<endl;
// cin.getline(cmd_str,500);something like this with the array from the function
cout<<cmd_str<<endl; this would print out the entire array
cout<<"test2"<<endl;
length=0;
length= shell(cmd_str);// so I could pass it to this function
You could use a string stream:
char const * p = get_data(); // assume null-terminated
std::istringstream iss(std::string(p));
for (std::string line; std::getline(iss, line); )
{
// process "line"
}
If the character array is not null-terminated but has a given size N, say std::string(p, N) instead.
First, if cmd_str is an array of char and infile returns a pointer to a string, that first assignment will give you an error. It tries to assign a pointer to a single char.
What you seem to want is strncpy:
strncpy(cmd_str, infile() ARRAY_LENGTH - 1);
cmd_str[ARRAY_LENGTH - 1] = '\0';
I make sure to add the string terminator to the array, because if strncpy copies all ARRAY_LENGTH - 1 characters, it will not append the terminator.
If cmd_str is a proper array (i.e. declared like char cmd_str[ARRAY_LENGTH];) then you can use sizeof(cmd_str) - 1 instead of ARRAY_LENGTH - 1 in my example. However, if cmd_str is passed as a pointer to a function, this will not work.
How do I append a string to a char?
strcat(TotalRam,str);
is what i got but it does not support strings
std::String has a function called c_str(), that gives you a constant pointer to the internal c string, you can use that with c functions. (but make a copy first)
Use + on strings:
std::string newstring = std::string(TotalRam) + str;
If you want it as a char[] instead, you need to allocated memory on the heap or stack first. After that, strcat or sprintf are possible options.
You can't append a string to a char, you can only append a string to a string (or a char* if using the C string functions). In your example, you'll have to copy (the char) TotalRam into a string of some sort, either a C++ std::string, or make a char[2] to hold it and the required terminating NULL character. Then you can either use the C++ string with C++ functions or the char[2] with strcat and friends.
for performance, do this:
char ministring[2] = {0,0};
// use ministring[0] as your char, fill it in however you like
strcat(ministring,str);
The char array is stack-allocated so it is extremely fast, and the second char with the value of zero acts as a string terminator so that functions like strcat will treat it as a 'c' string.