View Single Post
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