Page 1 of 2

Help with "Text Contains"

Posted: 26 Nov 2010, 18:07
by dudmaster
Hello, peeps!

I need to do a command just like the Text Contains block but in NXC...
TextContains.jpg
TextContains2.jpg

Re: Help with "Text Contains"

Posted: 26 Nov 2010, 19:44
by physics-matt
There doesn't appear to be a built in function, but this will probably work:

Code: Select all

bool IsIncluded( string s1, string s2 )
{
  bool included = false;
  for (int i = 0; i < (StrLen(s2)-StrLen(s1)) && !included; i++)
  {
   included = ( strcmp( s1, SubStr( s2, i, StrLen(s1) ) ) == 0 );
  }
  return included;
}
I've not tested it, so it may need tweaking to work properly, but it should give you enough of an idea.

HTH

Matt

Re: Help with "Text Contains"

Posted: 26 Nov 2010, 20:12
by dudmaster
Thx, i will modify to make it work... this is advanced! i'll see what i can do. (i sorta understand)

Re: Help with "Text Contains"

Posted: 26 Nov 2010, 20:59
by physics-matt
No problem. If you do have to modify the code for it to work, be sure to post a copy here.

At any rate, I'm sure you will learn a lot by going through it.

Matt

Re: Help with "Text Contains"

Posted: 28 Nov 2010, 16:43
by dudmaster
What does the command "strcmp" do?

Re: Help with "Text Contains"

Posted: 28 Nov 2010, 18:59
by mightor
string compare :)

- Xander

Re: Help with "Text Contains"

Posted: 28 Nov 2010, 20:49
by physics-matt
Be sure to read the documentation on strcmp carefully. People often get it wrong first time because it doesn't quite work as they expect ;)

Re: Help with "Text Contains"

Posted: 28 Nov 2010, 20:54
by dudmaster
I see. Well, i have the NXT-G "String Compare" block. I'll study. Thx! ;)

Re: Help with "Text Contains"

Posted: 28 Nov 2010, 20:56
by dudmaster
I see. Well, i have the NXT-G "String Compare" block. I'll study. Thx! ;)

EDIT: It's like this:

Code: Select all

if (Str1 == Str2)
{
//Stuff
}

Re: Help with "Text Contains"

Posted: 29 Nov 2010, 23:46
by afanofosc
I don't seem to have a copy of this NXT-G block. Can you tell where you got it from? It might be quite simple to generate an RXE file containing this block and then decompile it to see how it was implemented in NBC code and then translate that into NXC. The cString group of functions in NXC is intended to eventually include the "strstr" function which, in C/C++, returns a char * to the position of str2 in str1 or a null pointer if it is not found.

http://www.cplusplus.com/reference/clib ... ng/strstr/

I would implement it with a signature something like this in NXC:

string strstr(string str1, string str2);

The strcmp API function in NXC is very inefficient if you don't need to know < or > which in this case you don't. So I would just use == to compare the output of SubStr with the value of s1. I would also pre-calculate the length of s1 and the difference between the two string lengths. Also, you need to allow for equal length strings by using <= rather than just <. Like this:

Code: Select all

bool IsIncluded( string s1, string s2 )
{
  bool included = false;
  int l1 = StrLen(s1);
  int lDelta = StrLen(s2)-l1;
  for (int i = 0; i <= lDelta && !included; i++)
  {
   included = (s1 == SubStr( s2, i, l1 ) );
  }
  return included;
}
Here's a slightly more efficient version that uses a repeat loop rather than a for loop:

Code: Select all

bool IsIncluded( string s1, string s2 )
{
  int l1 = StrLen(s1);
  int lDelta = StrLen(s2)-l1;
  int i = 0;
  repeat(lDelta+1)
  {
    if (s1 == SubStr( s2, i, l1))
      return true;
    i++;
  }
  return false;
}
And here's a hand-tuned asm block version that may be instructive as to how the NXC API is defined in a lot of cases:

Code: Select all

asm {
dseg	segment
  __IsIncluded_i sword
  __IsIncluded_l1 sword
  __IsIncluded_lDelta sword
  __IsIncluded_tmpstr byte[]
  __IsIncluded_s2 byte[]
  __IsIncluded_s1 byte[]
  __IsIncluded_Result byte
  __IsIncluded_Mutex mutex
dseg	ends

subroutine __IsIncluded
	arrsize __IsIncluded_l1, __IsIncluded_s1
	sub __IsIncluded_l1, __IsIncluded_l1, 1
	arrsize __IsIncluded_lDelta, __IsIncluded_s2
	sub __IsIncluded_lDelta, __IsIncluded_lDelta, __IsIncluded_l1
	set __IsIncluded_i, 0
__IsIncluded_Repeat:
	sub __IsIncluded_lDelta, __IsIncluded_lDelta, 1
	brtst 0, __IsIncluded_RepeatEnd, __IsIncluded_lDelta
	strsubset __IsIncluded_tmpstr, __IsIncluded_s2, __IsIncluded_i, __IsIncluded_l1
	cmp 4, __IsIncluded_Result, __IsIncluded_s1, __IsIncluded_tmpstr
	brtst 4, __IsIncluded_RepeatAgain, __IsIncluded_Result
	return
__IsIncluded_RepeatAgain:
	add __IsIncluded_i, __IsIncluded_i, 1
	jmp __IsIncluded_Repeat
__IsIncluded_RepeatEnd:
	set __IsIncluded_Result, 0
	return
ends
}

#define IsIncluded(_s1, _s2) \
asm { \
  acquire __IsIncluded_Mutex \
  mov __IsIncluded_s1, _s1 \
  mov __IsIncluded_s2, _s2 \
  call __IsIncluded \
  mov __RETVAL__, __IsIncluded_Result \
  release __IsIncluded_Mutex \
}
John Hansen