Valhalla Legends Archive

Programming => General Programming => C/C++ Programming => Topic started by: Eli_1 on April 28, 2004, 12:50 PM

Title: Quick strtok question
Post by: Eli_1 on April 28, 2004, 12:50 PM
Making a simple client for bnet using CHAT protocol. I want to split the data received by b.net using strtok.

char *ptok = strtok(buffer, "\r\n");
   while (ptok != NULL) {
       printf("%s\n", ptok);
       ptok = strtok(NULL, "\r\n");
   }

It works, to an extent, but the output is kinda weird.
Output in BW client:
Quote
<some_loser is a Statistics Bot>
<Eli_1> hi
<Eli_1> h2
<Eli_1> hi2
<Eli_1> hi22
Weird output:
Quote
1005 TALK Eli_1 0010 "hi"
tistics Bot"
1005 TALK Eli_1 0010 "h2"
tistics Bot"
1005 TALK Eli_1 0010 "hi2"
istics Bot"
1005 TALK Eli_1 0010 "hi22"
stics Bot"
Anyone have an idea why this is happening?

Title: Re:Quick strtok question
Post by: K on April 28, 2004, 01:09 PM
I don't know the internal workings of strok, but it looks like it's not putting a null terminator after the substring it returns, so you're seeing whats left at the end of the buffer.
Title: Re:Quick strtok question
Post by: Adron on April 28, 2004, 01:32 PM
Looks like you're not putting a \0 at the end of buffer before calling strtok.
Title: Re:Quick strtok question
Post by: Eli_1 on April 28, 2004, 01:55 PM
I wasn't before. I changed it, but the output still isn't changing.

      buffer[strlen(buffer)] = 0;
      ptok = strtok(buffer, "\r\n");
      while (ptok != NULL) {
         printf("%s\n", ptok);
         ptok = strtok(NULL, "\r\n");
      }
Title: Re:Quick strtok question
Post by: Mephisto on April 28, 2004, 02:49 PM
I don't think he's talking about setting it to 0...NULL terminator perhaps?
Title: Re:Quick strtok question
Post by: Adron on April 28, 2004, 03:46 PM
0 or '\0' or NULL; all the same.

However, you're missing the point. Your problem is that you have a buffer containing text. The buffer is larger than the actual data in it. You have some length variable telling you how much data there is in the buffer. You have not put a string termination character at the end of the valid data.

Your recent addition

buffer[strlen(buffer)] = 0;

does nothing useful. By definition, the character buffer[strlen(buffer)] is zero already. That's what strlen checks for to find the length. And what strtok uses to find the end of the string.
Title: Re:Quick strtok question
Post by: Skywing on April 28, 2004, 04:12 PM
Note that NULL is typically defined as (void*)0 with C.  At least in GCC, you'll get warnings about assigning pointers to integers if you assign NULL to a char.
Title: Re:Quick strtok question
Post by: Adron on April 28, 2004, 04:21 PM
That's strange. You shouldn't be able to assign a void* to any other pointer type without a warning/error.
Title: Re:Quick strtok question
Post by: Eli_1 on April 28, 2004, 04:30 PM
Ahh, thank you very very much Adron. I totally forgot recv() returns the number of bytes received,  and I can just use that to put a null-terminator at the end of the data. Works like a charm now.  ;D


Quote from: Mephisto on April 28, 2004, 02:49 PM
I don't think he's talking about setting it to 0...NULL terminator perhaps?
Character arrays don't hold the actual character. Instead, they hold the number representation of that char.

str[5] = '\0x00';
str[5] = 0x00;
str[5] = '\0';
str[5] = 0;
str[5] = '(char)0';

Would all be null-terminators.
Title: Re:Quick strtok question
Post by: Skywing on April 29, 2004, 04:09 PM
Quote from: Adron on April 28, 2004, 04:21 PM
That's strange. You shouldn't be able to assign a void* to any other pointer type without a warning/error.
I think the rule about 0 implicitly casting still applies...
Title: Re:Quick strtok question
Post by: Adron on April 29, 2004, 05:38 PM
Quote from: Skywing on April 29, 2004, 04:09 PM
Quote from: Adron on April 28, 2004, 04:21 PM
That's strange. You shouldn't be able to assign a void* to any other pointer type without a warning/error.
I think the rule about 0 implicitly casting still applies...


   char *a = (void*)0;


Quote
templatetest.cpp: In function `int main ()':
templatetest.cpp:8: cannot convert `void *' to `char *' in initialization
Title: Re:Quick strtok question
Post by: K on April 29, 2004, 05:55 PM
I was under the impression that NULL was a (void*)0 in C and simply 0 in C++

(C++ Standard:)
Quote
4.10 - Pointer conversions
-1- A null pointer constant is an integral constant expression rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (conv.qual).
Title: Re:Quick strtok question
Post by: mynameistmp on May 03, 2004, 08:58 PM
"Never use these functions." - Linux strtok (and strtok_r) man file.