.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Programming (http://forums.bots-united.com/forumdisplay.php?f=25)
-   -   strings aaaaaaaaaaarghhhhhhhhh (http://forums.bots-united.com/showthread.php?t=1286)

stefanhendriks 07-04-2004 23:31

strings aaaaaaaaaaarghhhhhhhhh
 
I am getting nuts of this! Especially because i do the same thing twice, and one works one does not.

Okay, let me explain. I have a string, 80 characters, declared as:

Code:

class cChatEngine
{
public:
 // variables
 tReplyBlock ReplyBlock[MAX_BLOCKS]; // 100 reply blocks reserved in memory 
 float fThinkTimer;        // The chatengine has a 'think timer'.
 char sender[30];
 char sentence[80];

 // functions
 void init();  // initialize database/blocks
 void load();  // load database (loads blocks)
 void think();  // make the chat engine think
 bool cChatEngine::CompareNames(char name[30], char name2[30], int length);
 // add sentence from any player/bot into memory to handle
 void set_sentence(char *sender, char *sentence);
 // handles a sentence, decides to reply on it or not.
 void handle_sentence();
};

As you can see above, there is:

char sentence[80];

this one gets initialized:

sentence[0] = '\0';

in init();

So far so good, it gets filled in when a user says something (intercepting SayText, this also works okay (btw, code partially just copied from podbot source as i wont invent the wheel twice):

Code:

void BotClient_CS_SayText(void *p, int bot_index)
{
 static unsigned char ucEntIndex;
 static int state = 0;  // current state machine state
 if (state == 0)
 {
  ucEntIndex = *(unsigned char *)p;
 }
 else if (state == 1)
 {
  cBot *pBot=&bots[bot_index];
  if(ENTINDEX(pBot->pEdict) != ucEntIndex)
  {
  char sentence[80];
  char chSentence[80];
  char netname[30]; 
  strcpy(sentence,(char *)p);
  // remove first part of sentence.
  int length = strlen (sentence) - strlen (strstr (sentence, " : "));
 
  int tc=0;
  for (int c=length; c < 80; c++)
  {
        chSentence[tc] = sentence[c];
        tc++;
  }
  //strncpy (chSentence, (char *)sentence[length], 80-length);
  strcpy(netname, STRING(pBot->pEdict->v.netname));
 
  ChatEngine.set_sentence(netname, chSentence);
  }
 }
 state++;
}

Now do not ask me why i use so many different types of 'copying the string'. THis is because my problem will be described soon and i tried multiple manners of copying/reading strings.

Okay, now, the set_sentence function:
Code:

void cChatEngine::set_sentence(char csender[30], char csentence[80])
{
 if (sender[0] == '\0')
 {
  sprintf(sender, "%s", csender);
  sprintf(sentence, "%s", csentence);
 }
 else
  SERVER_PRINT("Tried to set sentence while we did not handle it yet");
}

Works fine as well,

here is the problem!!!:

as soon as i try to read ONE character from the line, it does not work, ie:

Code:

sprintf(msg, "%s", sentence[1]);
this will compile fine, but will CRASH in half-life/steam in this line!. When you try to do this:
Code:

sprintf(msg, "%s", &sentence[1]);
it compiles, and it will simply give me the string starting from 1. This does NOT crash:

Now here is a little code that should check the sentence PER CHARACTER, and then copy characters into words. I know it should work, because i have a function working almost the same way (it reads out the character the same way) and i do not have trouble there.

Code:

  // Scan the message so we know in what block we should be to reply:
  char word[20];
  int c=0;
  for (c=0; c < 20; c++)
        word[c] = '\0';
  c=0;
  int wc=0;
  int length = strlen(sentence);
  if (length == 0 || length > 80)
  {
        SERVER_PRINT("PROBLEM!");
        return;
  }
  int WordBlockScore[MAX_BLOCKS];
  for (int wbs=0; wbs < MAX_BLOCKS; wbs++)
        WordBlockScore[wbs] = -1;
  char chSentence[80];
  sprintf(chSentence, "%s", sentence);
 
  // C 
  while (c < length)
  {
        // get out
        if (c >= length)
        break;
        if (c < 0)
        break;
        if (sentence[c] == '\0')
        {
        c++;
        SERVER_PRINT("Found weird thingy, breaking out");
        break;
        }
       
//////////// PROOOOBBBBLLEEEEEM
///// here i get tons of messages "this is not a good word". It says word is zero length!
//// It seems like the sentence is read out entirely with empty strings or something? The sentence starts with a letter and still it goes into this IF block (after several checks).
// SOMEHOW I NEED TO READ THE CHARACTER AND I GET NUTS, IT SHOULD BE SIMPLE AND STILL IT DOES NOT WORK , I GET FUCKING NUTS ABOUT THIS. I SPENT THE FREAKING WHOLE DAY ON THIS MINOR PROBLEM AND IT SHOULD JUST WORK ARH. Its getting late. darn.
        if (sentence[c] == ' ');
        {
        // done with this word, find it in one of our blocks and give the block       
        // that score:
        if (strlen(word) <= 0)
        {
          SERVER_PRINT("This is not a good word!\n");
        }
        else
        {
          for (int iB=0; iB < MAX_BLOCKS; iB++)
        {
          if (ReplyBlock[iB].bUsed)
          {
          for (int iBw=0; iBw < 10; iBw++)
          {
          // add score
          if (strcmp(ReplyBlock[iB].word[iBw], word) == 0)
          {
                char msg[80];
                sprintf(msg, "Compared words: %s and %s -> added score to block %d\n", ReplyBlock[iB].word[iBw], word, iB);
                SERVER_PRINT(msg);
               
                WordBlockScore[iB]++;
               
          }
          }
          }
        }
        }
        // new word:
        word[0] = '\0';
        wc=0;
        c++;
        continue;
        }
        // fill in the word:
        word[wc] = sentence[c];
        c++;
        wc++;
  }
  // now loop through all blocks and find the one with the most score:
  int iMaxScore=-1;
  int iTheBlock=-1;
  for (int rB=0; rB < MAX_BLOCKS; rB++)
  {
        if (WordBlockScore[rB] > iMaxScore)
        {
        iMaxScore = WordBlockScore[rB];
        iTheBlock = rB;
        }
  }
  if (iTheBlock > -1)
  {
        char msg[80];
        sprintf(msg, "Choosen to reply from Block %d", iTheBlock);
        SERVER_PRINT(msg);
  }

okay, obvious question:
- does anybody know what is wrong?
- does anybody know why this function does work, but the above not?:
Code:

void
INI_Word (char input[80], char word[25])
{
  int pos = 0;
  int word_pos = -1;
  // clear out entire string
  for (int i = 0; i < 25; i++)
        word[i] = '\0';
  while (pos < 79)
        {
          if (input[pos] == '=')
  {
        word_pos = pos;
        break;
  }
          pos++;
  }
  if (word_pos > -1 && word_pos < 23)
        {
          for (int wc = 0; wc < word_pos; wc++)
 word[wc] = input[wc];
          word[word_pos] = '\0'; // terminate string 
        }
}


KickBot 08-04-2004 00:01

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Just scanned your code and found this typo where you seem to have located your problem:

if (sentence[c] == ' ');
{
...

the extra ; might be a nuisance 8o :D

I didn't check the code seriously but if all you do is string copying you could just use strcpy() instead of the combo sprintf(sTo,"%s",sFrom).

Hope this helps. I'm going to bed now too. Goodnight :)

MusicMan 08-04-2004 00:02

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Now I am not a geek at C++ but it looks like you declared "word[c]" to be '\0' and your problem comes when "strlen(word)" is less than or equal to "0" which is NULL right?. Just trying to help but dont think that I am:D

MusicMan

Artello 08-04-2004 00:08

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Hm, you are declared word[c] initialized it to be zero-string, never changed its value ... it always be with zero length :) That is why you are gettin tons of messages "this is not a good word"

Pierre-Marie Baty 08-04-2004 09:43

Re: strings aaaaaaaaaaarghhhhhhhhh
 
You're tired, Stefan... Get more sleep :)
Quote:

here is the problem!!!:

as soon as i try to read ONE character from the line, it does not work, ie:
Code:

sprintf(msg, "%s", sentence[1]);

...might work better if you were doing
sprintf (msg, "%c", sentence[1]);
instead, hmmm ? :)

If you do
sprintf (msg, "%s", sentence[1]);
and your "sentence" is something like "Hello my name is Stefan\n", you ask printf() to print out the STRING ("%s") that starts at the ADDRESS described by the 2nd element in the sentence[] array, that is, sentence[1] being 'ello' (since an int does 4 bytes), printf() will go and look for a string at address 0x656c6c7f (which is "ello" in hex) in memory, which is probably not what you want it to do !!!

stefanhendriks 08-04-2004 10:20

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Kickbot, i love ya. PMB you too!

The ; already caused tons of problems. I removed the ; and it already gives me only a few "not a good word" thingies. PMB, the character printing now works too so it does not crash. phew.

Okay, now i know the function grabs words okay, it only does not recognize them yet. but i think i can manage from here. If not i'll let ya know :)

Cheeseh 08-04-2004 13:17

Re: strings aaaaaaaaaaarghhhhhhhhh
 
always use char pointers (char*) in function parameters, makes it easier for me :P

stefanhendriks 08-04-2004 15:29

Re: strings aaaaaaaaaaarghhhhhhhhh
 
In writing its easier, but i'd rather know what i allocate instead of using pointers and 'can be any size' chars.

Rick 08-04-2004 18:05

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Quote:

sprintf (msg, "%c", sentence[1]);
Actually I think msg[0] = sentence[1] is more efficient :)

@$3.1415rin 08-04-2004 18:28

Re: strings aaaaaaaaaaarghhhhhhhhh
 
as long as you don't wanna change msg any more ...

botmeister 08-04-2004 18:29

Re: strings aaaaaaaaaaarghhhhhhhhh
 
If you are into C++ programming, then why not make use of the standard string class? It works nicely and is far simpler than using character arrays.

Rick 08-04-2004 18:44

Re: strings aaaaaaaaaaarghhhhhhhhh
 
Quote:

Originally Posted by @$3.1415rin
as long as you don't wanna change msg any more ...

Why?? I think its basicly just the same but you save a function call.

@$3.1415rin 08-04-2004 19:57

Re: strings aaaaaaaaaaarghhhhhhhhh
 
oops, sorry, I was thinking in terms of pointers :)

and stefan : don't be so stupid to implement some kind of 1337 chat generator in your chat system ;) I still get mails of users telling me about this "bug" :D *g* but I leave it there ... somehow it looks cool :)


All times are GMT +2. The time now is 16:22.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.