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