Page 1 of 1

A question or two regarding wxCTB

Posted: Thu Oct 19, 2006 3:27 am
by RogerFurer
Aloha from Honolulu,
I've been involved in other things and haven't had much time to do any coding until recently. I've managed to get the wxCTB sample: "CTB_Test.cpp" to compile and run in a cosole window. I used HyperTerminal on my pentium-2 Win98 computer for something to send to/receive from (the remote computer).
By extending the length of the timeout I had time to send an answer back to the wxCTB window. I was able to use different baud rates and I consider the experiment a success.
My first question has to do with the receivedBytes variable. This counts the bytes from the remote computer and reports the number at the end of the received string:

Code: Select all

      char* receivedBytes = NULL;
      int rd = dev->ReadUntilEOS(&receivedBytes,"\n",5000);

      if(rd > 0) {
         receivedBytes[rd] = 0;
         printf("answer (%i): %s\n",rd,receivedBytes);
      }
My first inclination was to comment out the line that sets receivedBytes to 0, thinking it was a mistake. However this caused garbage characters to appear in the received string and other oddities, so I put it back. But I don't understand why it works. Can someone explain this?

My second question is how to use the other read and write functions that are part of the tool box. The sample program uses Writev to send to the port and ReadUntilEOS to read from the port.
I notice that ReadUntilEOS is the only one with wxIOBase:: as part of the declaration and also that it is declared as virtual int. There are two other functions; Read and Write, which are declared as virtual int in wxIOBase, but they aren

Posted: Thu Oct 19, 2006 5:36 am
by Sof_T
wxwidgets:

char* receivedBytes = NULL;
int rd = dev->ReadUntilEOS(&receivedBytes,"\n",5000);

if(rd > 0) {
receivedBytes[rd] = 0;
printf("answer (%i): %s\n",rd,receivedBytes);
}


My first inclination was to comment out the line that sets receivedBytes to 0, thinking it was a mistake. However this caused garbage characters to appear in the received string and other oddities, so I put it back. But I don't understand why it works. Can someone explain this?
Hi Roger,
I'll explain the code line by line.

Code: Select all

char* receivedBytes = NULL;
This sets a pointer to a character string to point to NULL that is to nothing.

Code: Select all

int rd = dev->ReadUntilEOS(&receivedBytes,"\n",5000);
dev->ReadUntilEOS(&recievedBytes,"\n",5000); reads in all the characters upto a new line character "\n" and changes the pointer recievedBytes to point to it. It returns the number of charaters written and this value is written into rd.

Code: Select all

if(rd > 0) {
This checks rd to see if any bytes have been recieved that is more than zero.

Code: Select all

receivedBytes[rd] = 0;
This line is not good programming practice. It assigns the value zero to position rd in the character string. Since the string starts numbered from zero position rd is one character after the end of the recieved string. Since the char data type in C++ internally stores numbers like any other data type and the functions that use char translate this into the ASCII character that corresponds to that number. This line assigns the null or end of line character to the string.You can see this if you look at value zero on an ACSII chart like this one http://www.lookuptables.com/. Without this the printf function doesn't know where the line ends and continues to print from the computers memory until it finds a null character. This line is better written as

Code: Select all

receivedBytes[rd] = '0';
Your final line of code outputs the number of characters recieved and the string.

I hope this helps.

Sof.T[/url]

Posted: Thu Oct 19, 2006 6:45 am
by tiwag
Sof_T wrote: ... This line is better written as

Code: Select all

receivedBytes[rd] = '0';
this is not a good advice, and will obviously not work.
because code 0 (0x00) is necessary for zero terminated strings
as expected in a char* buffer...

and code of '0' is never defined as 0x00 ( e.g. 0x30 in ANSI char set)

assuming the buffer where receivedBytes points to is large enough,
receivedBytes[rd] = 0; is the correct way.

brgds, tiwag

Posted: Thu Oct 19, 2006 9:40 am
by RogerFurer
Aloha from Honolulu,
Thank you (mahalo, we say in Hawaii) for the info. My understanding of what you say is that receivedBytes[rd] is one past the last character of the string? So making it equal zero makes for a "null terminated string". A normal C-string.
But the int rd itself, is an integer variable that gets the count of characters received, true? Is rd located as part of the string; I mean could it be stored at an unrelated location? For some reason I imagined it as being at the beginning of the string (like a string that has the number of bytes in string[0]) or am I confusing myself needlessly?
Mahalo,
Roger

Posted: Thu Oct 19, 2006 2:19 pm
by Sof_T
:oops:
receivedBytes[rd] = '0';
I meant

Code: Select all

receivedBytes[rd] = '\0';
I shouldn't post just after waking up :wink:

since it is a char string it is better (for human readability) to assign a char. Assigning a number to a char buffer just increases the risk of confusion.

rd is just an integer number that stores the number of characters recieved. It has no relation to the string itself. As in it is not stored in the string. string[0] contains the first character in the string, string[1] contains the second character in the string and so on. So for a string of length 30 characters string[29] contains the last character. Therefore string[rd] points to the first character after the end of the string.

Sof.T

Posted: Fri Oct 20, 2006 7:30 am
by RogerFurer
Aloha from Honolulu,
OK, thanks again. I'm going to call this complete and start a new topic about the wxCTB functions.
Mahalo,
Roger