I'm think pointer is 4Byte or(2Byte) heap memory allocated
I need Structure data convert to char* Just need 12byte convert
this is my code
please Contact me.
thank you
struct MyData {
unsigned int myNumber;
float x;
float y;
};
int main(){
Mydata* mydata = new Mydata();
mydata->userNumber = 188242268;
mydata->x = 100.0f;
mydata->y = 102.0f;
char* sender = (char*)&mydata;
sioclient->send(sender);
// SocketIO Server Send
}
I don't think what you are asking is possible. string doesn't like having null characters in itself, which would be necessary to directly send the data (For example, a int(1) would have 1 NULL (0x0) character (modern systems would have 3 NULL characters) and 1 0x1 character, which string wouldn't like the null and terminate the string there).
I think you should find another networking library for what you are doing if you can't use WebSocket and need to have the efficiency of sending the bytes of a struct. (Boost::asio perhaps?)
But if you HAVE to use Cocos2d-x SIOClient without the WebSocket, then in the sending side, create a string with the values separated by commas:
string sendMe = to_string(mydata->userNumber) + "," + to_string(mydata->x) + "," + to_string(mydata->y);
And then on the receiving side:
Mydata receiver;
string recStr;//Received string
string temp;
int stage = 0;
for (int itr = 0; itr < temp.length(); itr++)
{
if (recStr[itr] == ',')
{
if (stage==0)
receiver.myNumber = stoi(temp);
else if (stage==1)
receiver.x = stof(temp);
stage++;
temp = "";
}
else
temp += recStr[itr];
}
receiver.y = stof(temp);
Hope that helps.
The old answer, in case you want to switch and have a solution:
Ok, try using the overloaded function
void send (const unsigned char * binaryMsg, unsigned int len);
instead. read about it here
This should look something like the following:
sioclient->send(reinterpret_cast<unsigned char*>(mydata), sizeof(MyData));
Tell me if you are using a different version of Cocos2d-x and thus this doesn't work, or if it failed to solve the problem. When I tried this, it compiled nicely and seemed to behave correctly.
If your compiler doesn't like unsigned char* for a const unsigned char* parameter, just add a const_cast.
Also, remember to delete (mydata); when you are done with it.
Related
I'm trying to base64 decode a string, then convert that value to a char array for later use. The decode works fine, but then I get garbage data when converting.
Here's the code I have so far:
std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);
char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0
decodedChar[decodedData.size() + 1] = 0; // terminate the string
for (size_t i = 0; i < decodedData.size(); ++i) {
decodedChar[i] = decodedData[i];
}
vector<BYTE> is a typedef of unsigned char BYTE, as taken from this SO answer. The base64 code is also from this answer (the most upvoted answer, not the accepted answer).
When I run this code, I get the following value in the VisualStudio Text Visualiser:
TestStringÍ
I've also tried other conversion methods, such as:
char* decodedChar = reinterpret_cast< char *>(&decodedData[0]);
Which gives the following:
TestStringÍÍÍýýýýÝÝÝÝÝÝÝ*b4d“
Why am I getting the garbage data at the end of the string? What am i doing wrong?
EDIT: clarified which answer in the linked question I'm using
char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0
Why would you manually allocate a buffer and then copy to it when you have std::string available that does this for you?
Just do:
std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);
std::string decodedString { decodedData.begin(), decodedData.end() };
std::cout << decodedString << '\n';
If you need a char * out of this, just use .c_str()
const char* cstr = decodedString.c_str();
If you need to pass this on to a function that takes char* as input, for example:
void someFunc(char* data);
//...
//call site
someFunc( &decodedString[0] );
We have a TON of functions and abstractions and containers in C++ that were made to improve upon the C language, and so that programmers wouldn't have to write things by hand and make same mistakes every time they code. It would be best if we use those functionalities wherever we can to avoid raw loops or to do simple modifications like this.
You are writing beyond the last element of your allocated array, which can cause literally anything to happen (according to the C++ standard). You need decodedChar[decodedData.size()] = 0;
I have a long array of char (coming from a raster file via GDAL), all composed of 0 and 1. To compact the data, I want to convert it to an array of bits (thus dividing the size by 8), 4 bytes at a time, writing the result to a different file. This is what I have come up with by now:
uint32_t bytes2bits(char b[33]) {
b[32] = 0;
return strtoul(b,0,2);
}
const char data[36] = "00000000000000000000000010000000101"; // 101 is to be ignored
char word[33];
strncpy(word,data,32);
uint32_t byte = bytes2bits(word);
printf("Data: %d\n",byte); // 128
The code is working, and the result is going to be written in a separate file. What I'd like to know is: can I do that without copying the characters to a new array?
EDIT: I'm using a const variable here just to make a minimal, reproducible example. In my program it's a char *, which is continually changing value inside a loop.
Yes, you can, as long as you can modify the source string (in your example code you can't because it is a constant, but I assume in reality you have the string in writable memory):
uint32_t bytes2bits(const char* b) {
return strtoul(b,0,2);
}
void compress (char* data) {
// You would need to make sure that the `data` argument always has
// at least 33 characters in length (the null terminator at the end
// of the original string counts)
char temp = data[32];
data[32] = 0;
uint32_t byte = bytes2bits(data);
data[32] = temp;
printf("Data: %d\n",byte); // 128
}
In this example by using char* as a buffer to store that long data there is not necessary to copy all parts into a temporary buffer to convert it to a long.
Just use a variable to step through the buffer by each 32 byte length period, but after the 32th byte there needs the 0 termination byte.
So your code would look like:
uint32_t bytes2bits(const char* b) {
return strtoul(b,0,2);
}
void compress (char* data) {
int dataLen = strlen(data);
int periodLen = 32;
char* periodStr;
char tmp;
int periodPos = periodLen+1;
uint32_t byte;
periodStr = data[0];
while(periodPos < dataLen)
{
tmp = data[periodPos];
data[periodPos] = 0;
byte = bytes2bits(periodStr);
printf("Data: %d\n",byte); // 128
data[periodPos] = tmp;
periodStr = data[periodPos];
periodPos += periodLen;
}
if(periodPos - periodLen <= dataLen)
{
byte = bytes2bits(periodStr);
printf("Data: %d\n",byte); // 128
}
}
Please than be careful to the last period, which could be smaller than 32 bytes.
const char data[36]
You are in violation of your contract with the compiler if you declare something as const and then modify it.
Generally speaking, the compiler won't let you modify it...so to even try to do so with a const declaration you'd have to cast it (but don't)
char *sneaky_ptr = (char*)data;
sneaky_ptr[0] = 'U'; /* the U is for "undefined behavior" */
See: Can we change the value of an object defined with const through pointers?
So if you wanted to do this, you'd have to be sure the data was legitimately non-const.
The right way to do this in modern C++ is by using std::string to hold your string and std::string_view to process parts of that string without copying it.
You can using string_view with that char array you have though. It's common to use it to modernize the classical null-terminated string const char*.
This question already has answers here:
C++ Reverse Array
(5 answers)
Closed 7 years ago.
This is an amateur question. I searched for other posts about this topic, found lots of results, but am yet to understand the concepts behind the solution.
This is a practice problem in my C++ book. It is not assigned homework. [Instructions here][1] .
WHAT I WOULD LIKE TO DO:
string input;
getline(cin, input); //Get the user's input.
int front = 0;
int rear;
rear = input.size();
WHAT THE PROBLEM WANTS ME TO DO
string input;
getline(cin, input); //Get the user's input.
int* front = 0;
int* rear;
rear = input.size();
Error: a value of type "size_t" cannot be assigned to an entity of type int*
This makes sense to me, as you cannot assign an 'address' of an int to the value of an int.
So my questions are:
What is the correct way to go about this? Should I just forget about initializing front* or rear* to ints? Just avoid that all together? If so, what would be the syntax of that solution?
Why would this problem want me to use pointers like this? It's clear this is a horrible usage of pointers. Without pointers I could complete this problem in like 30 seconds. It's just really frustrating.
I don't really see an advantage to EVER using pointers aside from doing something like returning an array by using pointers.
Thanks guys. I know you like to help users that help themselves so I did some research about this first. I'm just really irritated with the concept of pointers right now vs. just using the actual variable itself.
Posts about this topic that I've previously read:
[Example 1][2]
[Example 2][3]
[Example 3][4]
[1]: http://i.imgur.com/wlufckg.png "Instructions"
[2]: How does reversing a string with pointers works "Post 1"
[3]: Reverse string with pointers? "Post 2"
[4]: Reverse char string with pointers "Post 3"
string.size() does not return a pointer - it returns size_t.
To revert a string try this instead:
string original = "someText"; // The original string
string reversed = original; // This to make sure that the reversed string has same size as the original string
size_t x = original.size(); // Get the size of the original string
for (size_t i = 0; i < x; i++) // Loop to copy from end of original to start of reversed
{
reversed[i]=original[x-1-i];
}
If you really (for some strange reason) needs pointers try this:
string input;
getline(cin, input); //Get the user's input.
char* front = &input[0];
char* rear = &input[input.size()-1];
but I would not use pointers into a string. No need for it.
I guest you may not quite understand the problem here. This problem want you to COPY a C string then REVERSE it by pointer operation. There is no classes in standard C. So, the C string is quite different from string class in C++. It is actually an array of char-type elements ended with character '\0'.
After understand this, you may start to understand the problem here. If you want to copy a C string, you can not just use str_a = str_b. You need constructor here. However, in pure C style, you should REQUIRE memory space for the string at first (you can use malloc here), then copy each element. For example, you want to create a function to make a copy of input string,
#include <string.h>
char *strcopy(char* str_in) {
int len = strlen(str_in);
char *str_out = (char*)malloc(len+1);
char *in = str_in;
char *out = str_out;
while(*in != '\0') { *out++ = *in++; }
return str_out;
}
As you see, we actually use char* not int* here to operate string element. You should distinguish the pointer (such as in) and the element pointed by the pointer (such as *in) at first.
I'll show you a solution in pure C style for your problem, I hope this would help you to understand it. (You should be able to compile it without modification)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* strreverse(char* in){
// length of input string
int len = strlen(in);
// allocate memory for string operation
char *out = (char*)malloc(len+1);
// initialize <front> and <end>
char *front = out, *end = out + len - 1;
char buffer;
// copy input string
for(int i = 0; i <= len; i++){ out[i] = in[i]; }
// reverse string
for(; front < end; front++, end--) {
buffer = *front;
*front = *end;
*end = buffer;
}
return out;
}
int main() {
printf("REVERSE >> %s\n", strreverse("Hello, World!"));
return 0;
}
This is not you would do by C++ in actual programming, however, I guess the problem here is trying to let you understand mechanism of pointers. In this aspect, original C style would help a lot.
As always, problems with the pointers. I am trying to create a very simple "encryption/decryption" function for char arrays. Yes, I know I can use strings, but I want to improve my knowledge about pointers and make use of simple bytes to achieve a simple task.
So, I created a simple struct like this:
struct text {
char* value;
int size;
}
And I created this simple function:
text encrypt(text decrypted) {
char key = 'X';
for (int i=0; i<decrypted.size; i++) {
decrypted.value[i] = decrypted.value[i] ^ (key + i) % 255);
}
return decrypted;
}
At this point, an experienced C++ programmer should have spot the problem, I think. Anyway, I call this function like this:
...
text mytext;
mytext.value = new char[5];
mytext.value = "Hello";
mytext.size = 5;
mytext = encrypt(mytext);
...
I get, like always, a 'Segmentation fault(core dumped)' error. This is Linux, and, of course, g++. What have I done, again? Thanks!
mytext.value = new char[5];
mytext.value = "Hello";
on the second line, you throw away the (handle to the) allocated memory, leaking it, and let mytext.value point to a string literal. Modifying a string literal is undefined behaviour, and usually crashes, since string literals are often stored in a read-only memory segment.
If you insist on using a char*, you should strncpy the string into the allocated memory (but be aware that it won't be 0-terminated then, you should better allocate a new char[6] and copy also the 0-terminator).
Or let decrypt create a new text that it returns:
text encrypt(text decrypted) {
char key = 'X';
text encrypted;
encrypted.size = decrypted.size;
encrypted.value = new char[encrypted.size];
for (int i=0; i<decrypted.size; i++) {
encrypted.value[i] = decrypted.value[i] ^ (key + i) % 255;
}
// What about 0-terminators?
return encrypted;
}
But, as you're using C++, std::string would be a better choice here.
You're modifying string literals:
mytext.value = "Hello";
after this, you can no longer legally mutate what mytext.value points to, you can only re-assign the pointer.
The fix: use std::string
So, thanks for all the help guys, I am just have one last problem, I am putting the website source in a char var, and then reading the product title (I have gotten that), however it only works if I take part of the source, or only the html from one of the featured products on neweggs page. I think the program is crashing, because it doesnt know which title to pick when I need to get all three titles and put them into an array. Any ideas? Thanks. Here is the parser code:
http://paste2.org/p/809045
Any solution is greatly appreciated.
/**
* num_to_next -
* takes in a pointer to a string and then counts how many
* characters are until the next occurance of the specified character
* #ptr: the pointer to a string in which to search
* #c: char delimiter to search until
**/
int num_to_next(char *ptr, char c)
{
unsigned int i = 0;
for (i = 0; i < strlen(ptr); i++) {
if (ptr[i] == c) {
return i;
}
}
return -1;
}
/**
* space_to_underscore -
* this should help to alleviate some problems when dealing with
* filepaths that have spaces in them (basically just changes all
* spaces in a string to underscores)
* #string: the string to convert, yo
**/
int space_to_underscore(char *string)
{
for (unsigned int i = 0; i < strlen(string); i++) {
if (string[i] == ' ') {
string[i] = '_';
}
}
return 0;
}
char *file_name = (char *)malloc(sizeof(char *)); // allocate memory for where the app name will be stored
memset(file_name, 0, sizeof(file_name)); // zero the memory
char td_one[] = "<ul class="featureCells"><li id="ItemCell" class="cell">";
char *pstr = strstr(buffer, td_one) + strlen(td_one) + 6; // buffer is the source
char *poop = pstr + num_to_next(pstr, '>') + 1;
int blah = num_to_next(poop, '<');
strncpy(file_name, poop, blah);
// null terminate the string //
file_name[blah] = '\0';
space_to_underscore(file_name);
MessageBox(NULL, file_name, "Product Name", MB_OK);
free(file_name);
I'm not sure if these are your only problems, but...
First, you can't do char* filename = (char*)malloc(sizeof(char*)) (well, you can, but that's not what you actually want from your app).
What you want to have is char* filename = (char*)malloc(SIZE_OF_YOUR_STRING * sizeof(char));, so you can't allocate just an abstract buffer for your string and you have to know the expected size of it. Actually, here you don't have to write sizeof(char) because it always equals 1, but this sometimes this way of writing the code can help you(or somebody else) to understand that this block would store a string as array of chars).
Another example on the same problem: char* filename = (char*)malloc(65); - is ok and will allocate a block of memory to store 65 char symbols.
If we go further (where you're doing the memset), char* is a plain pointer and sizeof(filename) in your case would return the size of your pointer, but not your string. What you should write here is strlen(filename).