.:: Bots United ::.  
filebase forums discord server github wiki web
cubebot epodbot fritzbot gravebot grogbot hpbbot ivpbot jkbotti joebot
meanmod podbotmm racc rcbot realbot sandbot shrikebot soulfathermaps yapb

Go Back   .:: Bots United ::. > Developer's Farm > General Programming
General Programming Help others and get yourself helped here!

Reply
 
Thread Tools
strings aaaaaaaaaaarghhhhhhhhh
Old
  (#1)
stefanhendriks
RealBot Author
 
stefanhendriks's Avatar
 
Status: Offline
Posts: 3,088
Join Date: Nov 2003
Location: Netherlands
Default strings aaaaaaaaaaarghhhhhhhhh - 07-04-2004

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   
	}
}


Author of RealBot, "Arrakis" and "Dune 2 - The Maker" | co-Founder of Bots-United | Fundynamic | Blog | E-Mail me
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#2)
KickBot
Member
 
Status: Offline
Posts: 17
Join Date: Apr 2004
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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

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
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#3)
MusicMan
Member
 
Status: Offline
Posts: 236
Join Date: Feb 2004
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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

MusicMan
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#4)
Artello
Guest
 
Status:
Posts: n/a
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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"
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#5)
Pierre-Marie Baty
Roi de France
 
Pierre-Marie Baty's Avatar
 
Status: Offline
Posts: 5,049
Join Date: Nov 2003
Location: 46°43'60N 0°43'0W 0.187A
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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 !!!



RACC home - Bots-United: beer, babies & bots (especially the latter)
"Learn to think by yourself, else others will do it for you."
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#6)
stefanhendriks
RealBot Author
 
stefanhendriks's Avatar
 
Status: Offline
Posts: 3,088
Join Date: Nov 2003
Location: Netherlands
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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


Author of RealBot, "Arrakis" and "Dune 2 - The Maker" | co-Founder of Bots-United | Fundynamic | Blog | E-Mail me
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#7)
Cheeseh
[rcbot]
 
Cheeseh's Avatar
 
Status: Offline
Posts: 361
Join Date: Dec 2003
Location: China
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

always use char pointers (char*) in function parameters, makes it easier for me
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#8)
stefanhendriks
RealBot Author
 
stefanhendriks's Avatar
 
Status: Offline
Posts: 3,088
Join Date: Nov 2003
Location: Netherlands
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

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


Author of RealBot, "Arrakis" and "Dune 2 - The Maker" | co-Founder of Bots-United | Fundynamic | Blog | E-Mail me
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#9)
Rick
Council Member
 
Rick's Avatar
 
Status: Offline
Posts: 690
Join Date: Dec 2003
Location: Holland
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

Quote:
sprintf (msg, "%c", sentence[1]);
Actually I think msg[0] = sentence[1] is more efficient
  
Reply With Quote
Re: strings aaaaaaaaaaarghhhhhhhhh
Old
  (#10)
@$3.1415rin
Council Member, Author of JoeBOT
 
@$3.1415rin's Avatar
 
Status: Offline
Posts: 1,381
Join Date: Nov 2003
Location: Germany
Default Re: strings aaaaaaaaaaarghhhhhhhhh - 08-04-2004

as long as you don't wanna change msg any more ...


  
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
vBulletin Skin developed by: vBStyles.com