|
|
View previous topic :: View next topic |
Author |
Message |
guest Guest
|
strstr confusion |
Posted: Wed Mar 23, 2005 5:33 am |
|
|
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
|
|
Posted: Wed Mar 23, 2005 6:07 am |
|
|
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
|
|
Posted: Wed Mar 23, 2005 6:17 am |
|
|
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
|
|
Posted: Wed Mar 23, 2005 6:31 am |
|
|
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
|
|
Posted: Wed Mar 23, 2005 6:37 am |
|
|
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
|
|
Posted: Wed Mar 23, 2005 6:46 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 7:50 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 10:44 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 11:04 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 11:16 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 11:53 am |
|
|
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
|
|
Posted: Fri Apr 01, 2005 1:37 pm |
|
|
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
|
|
Posted: Sat Apr 02, 2005 1:44 pm |
|
|
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
|
|
Posted: Sat Apr 02, 2005 2:01 pm |
|
|
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
|
|
Posted: Sat Apr 02, 2005 2:52 pm |
|
|
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 |
|
|
|
|
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
|