CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

strstr confusion

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
guest
Guest







strstr confusion
PostPosted: Wed Mar 23, 2005 5:33 am     Reply with quote

Hi all,

I have written the following test function to understand strstr():

Code:

void test(void)
{
   char s1[10],s2[10];
   char r;

   strcpy(s1,"EF");   
   strcpy(s2,"ABCDEFG");
   
   r=strstr(s2,s1);

   printf(com1,"Result: %U",r);
}


As a result I get 180. I did expect 5 though, returning the location of s1 within s2.

Setting s1="HI" did return 0 as expected (not found)

Any idea what I'm doing wrong?
bluetooth



Joined: 08 Jan 2005
Posts: 74

View user's profile Send private message

PostPosted: Wed Mar 23, 2005 6:07 am     Reply with quote

The only thing you're doing wrong is misinterpreting the answer.... strstr returns a *pointer* to the occurence of the string, not the relative position of the occurence.

If you need the offset, use the source for strstr as a starting point and just return a counter.

Good luck....
guest
Guest







PostPosted: Wed Mar 23, 2005 6:17 am     Reply with quote

Thanks bluetooth for your reply.

I have read quite a bit about pointers but still find them difficult to use.

How would I go about getting the offset?
bluetooth



Joined: 08 Jan 2005
Posts: 74

View user's profile Send private message

PostPosted: Wed Mar 23, 2005 6:31 am     Reply with quote

It's returning the pointer to the location of the string in s2...

If you just say:

Code:
   strcpy(s1,"EF");   
   strcpy(s2,"ABCDEFG");
   
   r=strstr(s2,s1);
   
   r = r - s2 + 1; // added this line




Basically, you're taking off the base address of s2 from the answer. I added 1 to get you to the number you seek, because the answer returned is zero-based.

This is pointer math, and CCS (3.219) allows you to perform the operations with the variables as declared... even though r is a char and s2 is a pointer. It works, just might not be portable. I don't remember what the rule is for this.....

Have fun...
guest
Guest







PostPosted: Wed Mar 23, 2005 6:37 am     Reply with quote

Many thanks bluetooth, works fine now. (V3.221)

Do you know of a good reference or tutorial for pointers using CCS?
bluetooth



Joined: 08 Jan 2005
Posts: 74

View user's profile Send private message

PostPosted: Wed Mar 23, 2005 6:46 am     Reply with quote

Get Kernighan & Ritchie's "The C Programming Language"... it's the bible!

Pointers is pointers! CCS does them pretty much according to K&R with the exception of pointers to constants.
guest
Guest







PostPosted: Fri Apr 01, 2005 7:50 am     Reply with quote

Hi again,

I have been working on my code and have come to another stumbling block:

I am manipulating my own array and just add a 0x00 to the end (null) so I can use string functions like strstr().

I get strange results, so did some test with the previous little program I posted above.

What I get is:

test1() returns 4 (as expected)
test2() returns 238
test3() returns 0

I expected all 3 to return the value 4.

test2 is identical to test1 except for vars names
test3 uses my individually set array contents

Can anybody kindly explain what's wrong with my code or ist this a Compiler issue?

Thanks

My code:

Code:
#include "18F8720.h"      
#use delay(clock=3686400)         
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, errors)
#include <string.h>

// -------------------------------------------------------
void test1(void)
{
   char s1[10],s2[10];
   char r;

   strcpy(s1,"EF");   
   strcpy(s2,"ABCDEFG");
   r=strstr(s2,s1);
   r=r-s2;
   printf("Result: %U\r\n",r);
}
// -------------------------------------------------------
void test2(void)
{
   char t1[10],t2[10];
   char u;

   strcpy(t1,"EF");   
   strcpy(t2,"ABCDEFG");
   u=strstr(t2,t1);
   u=u-t2;
   printf("Result: %U\r\n",u);
}
// -------------------------------------------------------
void test3(void)
{
   char S1[10],S2[10];
   char r;

   s2[0]='A';
   s2[1]='B';
   s2[2]='C';
   s2[3]='D';
   s2[4]='E';
   s2[5]='F';
   s2[6]='G';
   s2[7]=0x00;      // null

   strcpy(S1,"EF");
   r=strstr(s2,s1);
   r=r-s2;
   printf("Result: %U\r\n",r);
}
// -------------------------------------------------------
void main()
{
   test1();
   test2();
        test3();
   while(1)
   {}        
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Apr 01, 2005 10:44 am     Reply with quote

Maybe its your compiler version. This is what I got:
Code:
Result: 4
Result: 4
Result: 4
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 01, 2005 11:04 am     Reply with quote

One problem is that he's taking the 16-bit pointer value returned by
the string function and he's stuffing it into an 8-bit char.
guest
Guest







PostPosted: Fri Apr 01, 2005 11:16 am     Reply with quote

Thanks for both your replies.

I have tried to use long vars now as in the new code below and still get the same problem:

test1() returns 4 (as expected)
test2() returns 65518
test3() returns 0

My compiler version is PCH 3.221

any other ideas apart from a compiler bug?

Code:

#include "18F8720.h"      
#use delay(clock=3686400)         
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, errors)
#include <string.h>

// -------------------------------------------------------
void test1(void)
{
   char s1[10],s2[10];
   long r;

   strcpy(s1,"EF");   
   strcpy(s2,"ABCDEFG");
   r=strstr(s2,s1);
    r=r-s2;
   printf("Result: %lu\r\n",r);
}
// -------------------------------------------------------
void test2(void)
{
   char t1[10],t2[10];
   long u;

   strcpy(t1,"EF");   
   strcpy(t2,"ABCDEFG");
   u=strstr(t2,t1);
    u=u-t2;
   printf("Result: %lu\r\n",u);
}
// -------------------------------------------------------
void test3(void)
{
   char S1[10],S2[10];
   long r;

   s2[0]='A';
   s2[1]='B';
   s2[2]='C';
   s2[3]='D';
   s2[4]='E';
   s2[5]='F';
   s2[6]='G';
   s2[7]=0x00;      // null

   strcpy(S1,"EF");
   r=strstr(s2,s1);
    r=r-s2;
   printf("Result: %lu\r\n",r);
}
// -------------------------------------------------------
void main()
{
   test1();
   test2();
  test3();
   while(1)
   {}        
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Apr 01, 2005 11:53 am     Reply with quote

PCM programmer wrote:
One problem is that he's taking the 16-bit pointer value returned by
the string function and he's stuffing it into an 8-bit char.


Isn't the default size of the pointer 8bit? I know on PCM it is. Maybe the PCH is different?

As for the code, here is what I tested:
Code:

#include "18F452.h"       
#fuses XT,NOLVP,PUT,NOWDT
#use delay(clock=4000000)         
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, errors)
#include <string.h>

// -------------------------------------------------------
void test1(void)
{
   char s1[10],s2[10];
   char r;

   strcpy(s1,"EF");   
   strcpy(s2,"ABCDEFG");
   r=strstr(s2,s1);
   r=r-s2;
   printf("Result: %U\r\n",r);
}
// -------------------------------------------------------
void test2(void)
{
   char t1[10],t2[10];
   char u;

   strcpy(t1,"EF");   
   strcpy(t2,"ABCDEFG");
   u=strstr(t2,t1);
   u=u-t2;
   printf("Result: %U\r\n",u);
}
// -------------------------------------------------------
void test3(void)
{
   char S1[10],S2[10];
   char r;

   s2[0]='A';
   s2[1]='B';
   s2[2]='C';
   s2[3]='D';
   s2[4]='E';
   s2[5]='F';
   s2[6]='G';
   s2[7]=0x00;      // null

   strcpy(S1,"EF");
   r=strstr(s2,s1);
   r=r-s2;
   printf("Result: %U\r\n",r);
}
// -------------------------------------------------------
void main()
{
   test1();
   test2();
        test3();
   while(1)
   {}         
}

And I tested it with 3.222, it works fine. So I'd suggest that you update your compiler. You can also set a break point before the printf and look at the contents of the var.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 01, 2005 1:37 pm     Reply with quote

Quote:
Isn't the default size of the pointer 8bit ?
The default size for PCH is 16 bits. In the symbol table below,
the compiler has assigned 2 bytes to ptr. I tested this with vs. 3.188.
Code:
SYMBOL TABLE
  LABEL                             VALUE

_RETURN_                          00000001
main.ptr                          00000006
main.ptr2                         00000008
PSP_DATA                          00000F83
C1OUT                             00000FB4

Code:
#include <18F458.h>
#fuses XT, NOWDT, NOPROTECT,PUT,BROWNOUT,NOLVP, CPD
#use delay(clock=4000000)

//============================
void main()
{
char *ptr;
char *ptr2;

while(1);
}
guest
Guest







PostPosted: Sat Apr 02, 2005 1:44 pm     Reply with quote

I have done some more tests:

- tried compiler versions 3.191, 3.221 and latest 3.222, all give the same wrong results, i.e.

test1: 4
test2: 238
tes3: 0

I then compiled the same above source for a 18F242 and bingo:

it works correctly, i.e.

test1: 4
test2: 4
test3: 4

So why woud I get the correct result when compiled for a 18F242 and wrong results when compiled for a 18F8720 ???

I guess the only difference is the header file *.h or are there any other differences within the compiler itself?

I'll have a look at the header files...

... don't I love this sort of thing ;-)
guest
Guest







PostPosted: Sat Apr 02, 2005 2:01 pm     Reply with quote

One other thing I found was that as I commented the testx() calls out, the next one down would show the coorect result i.e.:

as before:

void main()
{
test1();
test2();
test3();
while(1)
{}
}

will give: 4 / 238 / 0

Next, commenting out the first call:

void main()
{
//test1();
test2();
test3();
while(1)
{}
}

will give: 4 / 0

And finally, commenting out the first two:

void main()
{
//test1();
//test2();
test3();
while(1)
{}
}

will give: 4

Looks as if always the first call causes subsequent calls to give incorrect results.

Just thought another symptom might spark an idea somewhere of what's happening here...
Ttelmah
Guest







PostPosted: Sat Apr 02, 2005 2:52 pm     Reply with quote

First general comment, get out of the habit of using a variable to hold a pointer. Declare a pointer instead. Otherwise it makes it very likely that there will be a size problem, and this will 'come back to haunt you', if you move to other processors. So just declare the values as:
char *r;

For the first routine, and similarly for the latter routines. This then makes the code portable through the three possibilities so far (PCM/PCB, PCM/PCB, with #device *=16, and PCH). Yes PCH uses 16 bit pointers, this is why *=16, is redundant on these chips.

Now I have just compiled the code on 3.221, and it gives me correct results on both chips. Only two changes were implemented, I declared the values to hold the pointer results, as pointers, and I didn't use strcpy, but just declared the strings in the first two examples, with:
char s1[10] = "EF";
char s2[10] = "ABCDEF2;

Which makes the compiler initialise the strings for you.
I'd look very carefully through your code again. The answer '65518', could actually make sense, if the string declarations are incorrect, and the routine is searching through the entire possible 16bit address range, and then finding the requested string in the memory used by the routine 'before'.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group