Thread: Howto? split and use a char array

  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    9

    Howto? split and use a char array

    Hello people on this forum.. this is my first post here, but i'm sure i will post more and more as I'm working on a project with several students.. I hope I can learn a lot here. C++ isn't my first language to work with, so i might ask some silly questions..

    I have a server application written in c++, and a flash client. Currently I have managed to create a connection between the 2 programs.. They are meant to communicate with eachother. this works.

    The problem I have encountered is the following..

    Whenever i receive a package from the client i need to break this into several parts.. The problem is that all the packages are different sizes and the only thing they have in common at the moment is that the first two bytes are used to determine the package type.. Now i want to know how i can split the package the server receives, determine what kind of package it is, and discard the first two bytes. then send the data to the appropriate part of the application.

    The package is received through tcp and is saved to a char array..

    All the help is welcome, and if you need/want more information, let me know and i'll see what i can do.

  2. #2
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    I'll try to explain it a bit more
    Code:
    // headers
    
    using namespace std;
    
    int main()
    {
         char *temp1 = "03061988";
         char *temp2 = new char[3]; // target array
         // this is the char array I want to put the first 2 bytes from temp1 in.
         
    }
    
    void SplitArray(*temp1, int length, *temp2)
    {
         // Here I need some way to split temp1,
         // and put first part in temp 2, and the rest back in temp1
    }
    Plz ask me if things aren't clear..

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The contents of the memory pointed to by temp1 in your example cannot be safely modified, as it is a string literal.

    Code:
    length = 2;
    for (i = 0; i < 2; ++i)
        temp2[i] = temp1[1];
    temp2[2] = '\0';    // null terminator (C string convention)
    You can also do this;
    Code:
    const char *temp3 = temp2 + 2;
    to make temp3 point two characters into the string pointed at by temp1..... the const here ensures you can't accidentally overwrite the contents.

    What I've done is not exactly splitting the string but, depending on how you manage things, you achieve the same practical effect.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    For splitting, I'd use std::copy and boost::split (or whatever it's called).
    But it all depends on how you are doing it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    currently I receive an array of characters, and my intention is to check the first 2 bytes that are in that array. I am assuming that a character is the size of 1 byte. After that, I want to check the value that is held by the first 2 bytes together and after that, decide where the rest of the array should go (this will be done in a switch.. later concern for me..

    Because I will need to split the char array again later on I'd like to handle this in a seperate method. I have no problem putting the char array to a string if this would make it easier.

    For splitting, I'd use std::copy and boost::split (or whatever it's called).
    But it all depends on how you are doing it.
    About boost::split.. I'd rather not use too many external files, but I will definitly keep this part in mind..

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You could try something like...
    Code:
    // data is the data recieved from the network.
    int opcode = data[0] + (data[1] << 8);
    switch (opcode)
    {
    //...
    }
    Then, it depends on how you need to use the data. You could simply use a pointer to the beginning of the data, eg:
    Code:
    my_type_t * my_data = &data[2];
    Unfortunately, the standard library severely lacks good string manipulation routines such as splitting. Boost fills in that gap. I'd recommend that library to any C++ dev.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    it's been a while since i made this post, and I want to thank the people that responded. but despite the fact that I have been pointed in the right direction, not everything is clear to me.. I have been trying some stuff, and i get the idea..

    Now I have encountered the next problem as I'm trying to send and receive data from a Flash client application that uses XMLSockets. Ill supply the code from the client and the server. I believe the problem lies in the c++ code, but I can be wrong.

    I hope someoned can help me once more



    Flash Client Code
    Code:
    public function Main()
    {
    	// socket is created to send and receive data
            
    	// Next I create a byteArray that will contain the data to  be sent 	
    	var byteArray:ByteArray = new ByteArray();
    	//Add value to byteArray here
    	byteArray.writeUnsignedInt(1000);
    
            // strTotal is a string for testing purposes
    	var strTotal:String = new String();
    	trace("length: " + byteArray.length);
    	var j:Number = 0;
    	for (var i:Number = 0; i < byteArray.length; i++)
    	{
    		strTotal += byteArray[i];
    		strTotal += " ";
    		j++;
    		if (j == 4)
    		{
    			strTotal += "| ";
    			j = 0;
    		}
    	}
    	trace("strTotal: " + strTotal);
    	socket.send(byteArray);
    }
    Result:
    length: 4
    strTotal: 0 0 3 232 |
    Connected
    dataHandler data: Hallo
    As you can see, I'm sending an unsigned int with the value of 1000. This gets printed as
    0 0 3 232
    this is the value that is in the array.
    binary value =
    0000 0000 0000 0000 0000 0011 1110 1000

    I have recalculated this to decimal and it is 1000.
    Everyone still with me this far?

    Now i want to receive this data on my server. This has been made in c++ and I am
    using winsock to send and receive data. I have finished making my socket, and all of it works..
    My application is waiting for data to be received.

    I receive data with the recv() method
    Code:
    char tempBuffer[128];
    int retval = recv(tSocket, tempBuffer, sizeof(tempBuffer), 0);
    When I try to show the data on the screen I get wrong information
    this is done in the next piece of code

    Code:
    if (retval == 0)
    {
    	break;
    	// Connection has been closed
    	// Keep open maybe doing nothing??
    }
    else if (retval == SOCKET_ERROR)
    {
    	throw ErrorLogging("Socket error while receiving");
    }
    else
    {
    	// Handle received data
    	cout << "Incoming buffer length: " << retval << endl;
    	cout << "Buffer content: " << tempBuffer << endl;
    	// Byte 0 & 1 are empty, they are empty here as well
    	cout << "0: " << (unsigned short)tempBuffer[0] << endl;
    	cout << "1: " << (unsigned short)tempBuffer[1] << endl;
    	// For bytes 3 & 4 I try several things, but they all seem to interpret the data wrong
    	cout << "uint 2: " << (unsigned int)tempBuffer[2] << endl;
    	cout << "ushort 2: " << (unsigned short)tempBuffer[2] << endl;
    	cout << "char 2: " << (char)tempBuffer[2] << endl;
    	cout << "uchar 2: " << (unsigned char)tempBuffer[2] << endl;
    	cout << "uint 3: " << (unsigned int)tempBuffer[3] << endl;
    	cout << "ushort 3: " << (unsigned short)tempBuffer[3] << endl;
    	cout << "char 3: " << (char)tempBuffer[3] << endl;
    	cout << "uchar 3: " << (unsigned char)tempBuffer[3] << endl;
    	// This is what i should be getting, and iFirstValue should be 1000.. 
    	int iFirstValue = ((unsigned short)tempBuffer[0] << 24) + ((unsigned short)tempBuffer[1]
     << 16) + ((unsigned short)tempBuffer[2] << 8) + (unsigned short)tempBuffer[3];
    	cout << "First value = " << iFirstValue << endl;
    	for (int i = 0; i < retval; i++)
    	{
    		// Here i show the bytes again, 
    		
    		cout << "Byte " << i << ": " << (unsigned short)tempBuffer[i] << endl;
    		cout << "Binary byte " << i << ": " << bitset<CHAR_BIT>(tempBuffer[i]) << endl;
    	}
    	if (send(tSocket, temp, retvalue + 1, 0)==SOCKET_ERROR)
    	{
    		throw ErrorLogging("Socket error while sending.");
    	}
    	else
    	{
    		//Success in sending
    		cout << "Sending is a succes." << endl;
    	}
    Here I have an image of the output that is made.
    http://img267.imageshack.us/img267/8079/outputx.jpg

    Can someone plz explain why i cannot get the correct value that is sent.. I seem to be missing something or doing something wrong

    many thanks in advance

  8. #8
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Looks like to me your temp buffer is blank. What are you expecting it to be?
    Woop?

  9. #9
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    tempBuffer is expected to contain the data sent by the flash client (as you can see in the first part) the data sent is 4 bytes.. allthough the data received is 6 bytes. The last of these bytes is the '\0' terminator added for the char array. I can't seem to figure out why the 5th byte is there.. and why I cannot receive the value 1000... if i try value 1, 10 or 100, when sending with the flash client there is no problem and I receive the data correctly

  10. #10
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    What I was saying in your output, the tempBuffer was showing blank. So I am not sure if you are getting your data.

    Also may I ask why you are breaking the 1000 into pieces instead of passing the string "1000" to the server application and parsing it from there?
    Last edited by prog-bman; 07-22-2010 at 04:15 PM.
    Woop?

  11. #11
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    I have noticed that the buffer is empty, but why does the size of the buffer (retval) is 6.. and why can i convert the result to some value.. As you can see, the third byte does contain the value 3.. Also when i send the value of 1, 10 or 100, the server code does receive the correct value.. It seems that values over 255 are misread..

    as of sending of the string, I am taking this into consideration, but I am building the base for an application, and I want to start trying this since the data sent needs to be disected once arrived at the server.. I haven't decided what I want to do with this..

  12. #12
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Well I don't know. Perhaps the flash isn't sending what you are expecting. Can you show the code for how you deal with receiving the data from the socket?

    It all depends on what you are trying to accomplish(in regards to the string). I have done a lot of communicating between flash and a server app. Typically I use web services, but that is because I am using C# which makes that very easy to deal with. But back in the day some of the code I worked with sent query string separated values to the server.

    My recommendation to you is unless you want to offload some processing onto the client machine is to use whole strings and parse them into their expected values, using stringstreams
    Woop?

  13. #13
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    for receiving data, I do nothing more than create a socket, initialize it (I followed the C++ WinSock tutorial from Homepage - MadWizard.org, and then receive the data on the server. this is done by the winsock.recv() method as explained in the code above. All the code that has to do with the data handling can be found in my earlier post..

    Well a string could be an option for what I want to do, and I have tried sending data from the flash client as well.

    When I use
    Code:
    byteArray.writeObject("String");
    I get the following trace in flash:

    length: 8
    strTotal: 0 6 83 116 | 114 105 110 103 |
    Connected
    dataHandler data: Hallo

    and I get the following result on my server

    http://img842.imageshack.us/img842/7049/output2.jpg


    When i try to write an actual string with the following method
    Code:
    byteArray.writeUTF("String");
    I get the following trace and server result

    length: 8
    strTotal: 0 6 83 116 | 114 105 110 103 |
    Connected
    dataHandler data: Hallo

    http://img249.imageshack.us/img249/9089/output3.jpg

    here it seems that the trace puts out the same results, but I get other results @ the server..

    It also seems that the third byte (byte[2]) received on the server contains the 'S', whilst it should be in the first byte (byte[0]).. How is this possible.. Note that it happens when I send the Object or the UTF method..

  14. #14
    Registered User
    Join Date
    Jul 2010
    Posts
    9
    ok, I just found out (simply misreading the documentation) that writeUTF appends 16 bits with the length of the string to the beginning of the bytearray.. I also found that the writeUTFBytes does not do this.. but when i run this, I still do not get the correct data in the tempBuffer: in my screen output

  15. #15
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Right.

    I am sorry I have been mis-guiding you somewhat. I thought everything was being sent as a string already, but really behind the scenes that is not what is happing.

    Since you know exactly what data you are sending yourself you just need to convert the tempBuffer to the appropriate datatype.

    I have not worked with sockets in a while in C++ but basically you want to do something like this.
    Code:
    	std::vector<char> fullBuffer;	
    	char buffer[1] = {0};
    
    	int bytesRec = 0;
    	while((bytesRec = recv(clientSocket, buffer, 1, 0)) > 0){
    		fullBuffer.push_back(buffer[0]);		
    	}//while
    
    	char* fullOutput = new char[fullBuffer.size()];
    	for(int i = 0; i < fullBuffer.size(); i++){
    		fullOutput[i] = fullBuffer[i];
    	}//for
    
    	unsigned int value = *(reinterpret_cast<unsigned int*>(fullOutput));
    	delete fullOutput;
    I am sure there are better ways of doing this, but that is generally the idea.

    PS: This assumes both client and server use the same endianness. You could run into problems if they don't. But I leave that for you to work out
    Last edited by prog-bman; 07-23-2010 at 12:02 PM.
    Woop?

Popular pages Recent additions subscribe to a feed