View previous topic :: View next topic |
Author |
Message |
small_chick
Joined: 17 Jul 2012 Posts: 53
|
Error with function "stricmp" in string.h ? |
Posted: Tue Jul 24, 2012 7:31 pm |
|
|
When I tried to use functions in string.h, it had the following error:
*** Error 66 "C:\Users\USER\Desktop\lam_mach\PIC_projects\16F887\CCS C\string.h" Line 382(31,32): Previous identifier must be a pointer
Code: |
//code for function "stricmp" in string.h:
signed int8 stricmp(char *s1, char *s2)
{
for(; *s1==*s2||(isalpha(*s1)&&isalpha(*s2)&& (*s1==*s2+32||*s2==*s1+32)));
s1++, s2++;
if (*s1 == '\0')
return(0);
return((*s1 < *s2) ? -1: 1);
}
|
Error in "for" loop !
You can download my project here !!!
http://www.mediafire.com/?ewz4cwgc51ggs9w
Look forward to receiving your reply! thanks!
Last edited by small_chick on Wed Jul 25, 2012 2:17 am; edited 1 time in total |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jul 25, 2012 12:35 am |
|
|
CCS version? Processor type? The fault is probably in the calling code. |
|
|
small_chick
Joined: 17 Jul 2012 Posts: 53
|
|
Posted: Wed Jul 25, 2012 2:19 am |
|
|
Sorry for not giving you download link ! I have added link in first thread above! You can view it! |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jul 25, 2012 3:00 am |
|
|
small_chick wrote: | Sorry for not giving you download link ! I have added link in first thread above! You can view it! |
In this day and age of downloadable virii, no one's going to go to a site and download anything more than a text file (or image).
Please post a short compilable example here that displays the problem.
Follow this mantra: http://www.ccsinfo.com/forum/viewtopic.php?t=47549
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
small_chick
Joined: 17 Jul 2012 Posts: 53
|
|
Posted: Wed Jul 25, 2012 3:52 am |
|
|
bkamen, you mean I should post my full code or error statements of the compiler ??? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Jul 25, 2012 5:01 am |
|
|
No.
You should do what you should _always_ do with a problem like this. _Simplify_. Throw away just about all the code (OK keep it elsewhere_, but make a cut down program that _just_ has the basic code needed to call the function showing the fault). _Nothing else_. If the total length is more than perhaps 40 lines nobody will look at it.
The odds are when you do this, either you will see what the problem really is, or that it will start working, telling you that there is something syntactically wrong elsewhere in the code. If it still fails, then you have something you can post, which people can look at, and help you.
The error is saying that the variable being passed is _not_ a pointer. Are you _sure_ the variables being passed are pointers?. Remember that in CCS, something like "Fred", does _not_ default to passing a pointer, if placed as one of the values in a call like this. This is down to a 'residue' from the architecture of the processor, where constant data is in a separate memory space to the RAM, so a 'pointer' can't easily be constructed.
So:
stricmp("Fred",buffer);
where 'buffer' is a char array, _will_ give exactly this error, unless you have the option 'PASS_STRINGS=IN_RAM' selected.
Your 'for' though, is failing, because it is syntactically invalid. The for loop construct, required three elements, separated by two ';' between brackets. You have a non existent first element (fine), then a complex second element (Ow....), but no second ';' and no third element. The bracket then closes, and nothing else is executed for the for loop (trailing ';'...).
The programming is messy, making it difficult to see what is going on at all. Take advantage of #defines.
So:
Code: |
#define IS_EQUAL(x,y) (*x==*y)
#define BOTH_ALPHA(x,y) (isalpha(x) && isalpha(y))
#define 32_EQUAL(x,y) ((*x==*y+32)||(*y==*x+32))
signed int8 stricmp(char *s1, char *s2) {
for ( ; IS_EQUAL(s1,s2) || BOTH_ALPHA(s1,s2) || 32_EQUAL(s1,s2);) {
s1++;
s2++;
if (*s1== '\0')
return 0;
}
return((*s1 < *s2) ? -1: 1);
}
|
Even better consider writing a single function to do the three comparisons.
Also, learn to comment. Anyone _yourself included_ coming to this code in a year's time, won't have the blind hope in h&ll of working out what it is actually meant to do.
I'm not sure you do at this point, which is possibly why the syntax gets screwed....
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 25, 2012 5:21 am |
|
|
I do agree that the stricmp function is a terrible programming example but it does come from the CCS string.h file. That is to say, in my v4.077 the bug in the incorrect for-loop declaration is not present.
Which brings me to the simple rules we have here when people post a topic, and linked to by Bkamen three posts higher up.
ALWAYS POST YOUR COMPILER VERSION NUMBER !
It has been asked twice now but our small_chick just chooses to ignore this important issue and is wasting our time by using an old and unstable beta version of the compiler. |
|
|
small_chick
Joined: 17 Jul 2012 Posts: 53
|
|
Posted: Wed Jul 25, 2012 11:25 am |
|
|
sorry everyone, I think I'm too lazy! I have posted full code of my project, while I only asked a small part of it ! This caused you fed up with reading my code to help me !
I have edited code concentrating on my problem, here's my code:
Code: |
#include "16F887.h"
#device adc = 10 //configuring in ADC 10 bit mode
#use delay(clock = 4000000)
#use i2c(master,sda = PIN_C4, scl = PIN_C3)
#use delay(clock = 4000000)
#use RS232(UART1)
#include "string.h"
//*****************************************************************************
void uart_init()
{
setup_uart(9600);
}
//*****************************************************************************
//*****************************************************************************
void main()
{
uart_init();
//declaring variables in main
unsigned int i;
unsigned char s[17],opcode[3];
puts("------------");
while(1)
{
for(i=0;i<17;i++)
{
s[i] = getc();
if(s[i] == 's')
{
i=17;
break;
}
}
opcode[0] = s[0];
opcode[1] = s[1];
opcode[2] = s[2];
unsigned char pass_adc[3];
strcpy(pass_adc,"adc");
if(strcmp(opcode,pass_adc))
output_b(0x00);
}
//**************************************
//the end!
//*************************************
|
And this is error statement:
< *** Error 66 "C:\Users\USER\Desktop\lam_mach\PIC_projects\16F887\CCS C\string.h" Line 382(31,32): Previous identifier must be a pointer >
Line382 in string.h is "For" loop in function stricmp()!
In addition, I added two more header files "stddef.h" and "ctype.h", that supported string.h !!!
My CCS version is ver.4 !
If you need, I'll send you files: "string.h","stddef.h" and "ctype.h" of my CCS version to check !!! |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jul 25, 2012 12:34 pm |
|
|
Quote: | My CCS version is ver.4 ! |
That's no version. Latest version is e.g. 4.135. Your lastest code compiles fine in V4.135.
But it gives syntax errors in older versions, e.g. V4.099 because it uses C++ syntax, interleaved statements and variable definitions in main. Possibly the observed problem with stricmp() has to do with the definition of pass_adc.
The CCS stricmp() code in the first post is identical to the V4.135 version, except for an askew bracket. Don't know if it has been shipped with any CCS version or has been corrupted later. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jul 25, 2012 1:00 pm |
|
|
Wasn't it "standardized" at some point making it "best practice" to declare variables FIRST and followed by instructions that process data.
like C99 or something?
Anyway - I've ALWAYS declared variables first and followed by operational code. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 25, 2012 3:15 pm |
|
|
In addition to all the good tips given above:
- Why are there two '#use delay' lines?
- Where are the #fuses definitions?
- Why the separate call to setup_uart? You can specify the 9600 baud in the #use RS232 line.
- Always add the ERRORS directive to the '#use RS232' line. It will make the compiler add code for clearing possible buffer overflow errors that stall the UART.
- And a real bug: Code: | unsigned char pass_adc[3];
strcpy(pass_adc,"adc"); | The array is one byte too short as you have to include the terminating zero. Now the program will overwrite other data in RAM. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 25, 2012 4:46 pm |
|
|
The 'opcode' array has the same problem. There's no 0x00 byte added
to the end so it's not a string, and the 'opcode' array is to small to hold it
anyway. And the program expects strcmp() to return TRUE if the strings
match, but that is not what strcmp() actually returns in that case. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Jul 26, 2012 3:53 am |
|
|
Quote: | Wasn't it "standardized" at some point making it "best practice" to declare variables FIRST and followed by instructions that process data.
like C99 or something? |
Not only best practice. Standard C requires that a code block (either a complete function or compound statement between curly brackets) keeps the order
declaration(s) - statement(s).
In other words, a variable declaration can appear at the begin of a function or a block, but not at arbitrary places, as in the discussed code example.
K&R (2nd edition which fully reflects the ANSI C specification) clarifies in paragraph 4.8 block structure:
Quote: | Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function. Variables declared in this way hide any identically named variables in outer blocks, and remain in existence until the matching right brace. |
C++ allows in contrast to mix declarations and statements.
CCS C stopped complaining about misplaced declarations somwhere after V4.100, but I'm not sure if it's on purpose and guarantees correct code evaluation in every case. Thus I prefer to stay with specified C syntax. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Jul 26, 2012 9:09 am |
|
|
[quote="FvM"] Quote: |
K&R (2nd edition which fully reflects the ANSI C specification) clarifies in paragraph 4.8 block structure:
Quote: | Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function. Variables declared in this way hide any identically named variables in outer blocks, and remain in existence until the matching right brace. |
|
k, that's where I read it. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|