We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
hi how can you do a case insensitive string compare ? i'm using uvision3 , c51 version 8. the string.h don't know stricmp or strlwr. can i compile my own function ?
thanks gamba
can i compile my own function ?
Only you can answer that question ;)
There are plenty of open-source compilers - you could take a look at their implementations...
http://codesearch.google.com
Just note that open-source isn't the same as free source. If you are working with a commercial project - be careful with GPL-licensed code, since it taints your whole application with the GPL license. It is only the special case of linking with a LGPL:ed library that the tainting doesn't occur.
how can you do a case insensitive string compare ?
A simple solution is to convert all letters in the strings to one case (upper or lower), and then do a regular string compare.
hi it seems that the C51 is not supporting any function of lower or upper case convert. please advice.
thanks everyone!
it seems that the C51 is not supporting any function of lower or upper case convert.
Assumed that you are using the ASCII code, then converting between upper and lower case is a simple matter of adding or subtracting an offset from the character.
For example:
'A' = 0x41 'a' = 0x61 'a' - 'A' = 0x20
So in order to convert an upper case letter to lower case, just add 0x20. To convert lower to upper case, just subtract 0x20. Of course, you need to make sure that the character in question is actually a letter and not some other character, or you'll convert your string to garbage.
en.wikipedia.org/.../Ascii
How about just:
c = (c >= 'a' && c <= 'z') ? c - ('a'-'A') : c;
Yes, that's a neat way to convert from lower- to upper-case; it is left as an exercise for the student to apply a similar expression to make a case-insensitive compare...
stricmp() and its relatives are not standard C library functions. If I recall correctly, they're defined by one of the POSIX standards.
FreeBSD source for their C library can be found here. www.freebsd.org/.../
i understand that i am supposed to add the stricmp() to the c51 program somehow but i failed.
file.C(101): error C267: 'stricmp': requires ANSI-style prototype
file.C(101): warning C206: 'stricmp': missing function-prototype
this is all i get.
i used my own function to receive input and transform it to lower-case but when i call the function i get the same errors as above.
if i change the function to void it runs, but if i deliver a variable to the function i get the error above.
the code is
#include <stdio.h> #include <string.h> #include <REG52.H> #include <stdlib.h> #include <ctype.h> void main (void) { char *textBody; char *textbody2; char *password; char *lwrtext2; char *checkbody; char *path= "hello"; textBody = (char*)strchr(path,'\0'); textBody++; strcpy(textbody2,textBody); lwrtext2 = (char *)lwrbuffer(textbody2); if (strcmp(lwrtext2, "password" )==0) printf("password OK!"); scanf("%d", &n); } void lwrbuffer(checkbody) { int i; char *lwrtext; char *lowertextBody; i=0; for (;i <= strlen(checkbody);i++) { checkbody[i] = (checkbody[i] >= 'a' && checkbody[i] <= 'z') ? checkbody[i] - ('a'-'A') : checkbody[i]; lowertextBody[i] = checkbody[i]; } strcpy (lwrtext,lowertextBody); return (lwrtext) ; }
Any thoughts ?
Well done for using the correct tags to post your source code, but is that really how you lay it out?
Your indenting is quite bizarre! Have you used TABs? Don't use TABs, use spaces - TABs are entirely unreliable!
void lwrbuffer(checkbody) { int i; char *lwrtext; char *lowertextBody; i=0; for (;i <= strlen(checkbody);i++) { checkbody[i] = (checkbody[i]>='a' && checkbody[i]<='z') ? checkbody[i]-('a'-'A') : checkbody[i]; lowertextBody[i] = checkbody[i]; } strcpy (lwrtext,lowertextBody); return (lwrtext) ; }
You haven't defined the type of the parameter to lwrbuffer - 'C' will make an assumption, but it isn't what you want;
Why do you initialise i to zero in a separate statement outside the for loop?
You are converting each element of the checkbody array in-place - there is no need for all the messing about with copying to lowertextBody and lwrtext;
You are treating lowertextBody and lwrtext as if they were arrays - but they are just pointers;
You are returning a value in a void function.
Note that this is all standard 'C' - nothing specific to Keil nor the 8051 here!
You are overcomplicating things.
I think you should consider looking for a good book on programming in C - it seems like you are not familiar with C or C++.
By the way - is your posted source code a verbatim copy, or have you typed in the code again? The warning is about stricmp, I can't see any calls to stricmp - just a call to lwrbuffer() and strcmp(). My guess is that you hand-typed, and that the strcmp() should be stricmp(). Never type in the code when posting. Always select all code and then copy/paste. I repeat: Always copy/paste!
Anyway, this is a very incomplete list with problems in your program:
In main(), you are calling lwrbuffer() without having declared the prototype. Any functions that you create must either have their function body above the function that calls it, our you must explicitly add a function prototype - either at top of the source file or in one of your include files.
lwrbuffer() has return type void, which doesn't mean "returns any type" but means "does not return anything". So, you can't in main() just typecast the return from lwrbuffer() to (char*). There is nothing returned!
lwrbuffer() has return type void, but still contains code of the type return <value>. A function with return type void must either be without any return statement, or may only contain empty return statements, i.e.
void fnk(void) { return; }
lwrbuffer() is using old K&R-style parameter declaration, i.e. only the parameter name is specified. An you are following that up by the parameter being implied int. Your code should be:
char* lwrbuffer(const char* checkbody) { ... }
By the way - why calling the parameter checkbody? A function called lwrbuffer by definition should not need to know WHY you convert a string to lowercase - so why should the parameter imply that it is for some form of check?
main() constains the following code:
char *path= "hello"; textBody = (char*)strchr(path,'\0'); textBody++; strcpy(textbody2,textBody);
You first locate the terminating zero of the "hello" string, and then steps one step past. What do you expect to find there? That is an undefined memory location, so you can/must not try to perform that strcpy() operation!
You have the following line:
scanf("%d", &n);
It is expected to get characters from stdin (which may be an interesting concept for an embedded system) and scan for an integer. Shouldn't you check the return value of scanf() to see if an integer was received?
You are making quite a lot of copying - why? You can compare two strings on-the-fly without any copying. Just use two character pointers - one for each string. Convert the first character from each pointer to upper (or lower) case and compare. If different, you have an answer. If not different but any of the pointers point to a '\0' then you have reached the end of both strings, and they where equal. If not different and neither pointer pointed to '\0', then step both pointers forward one step and repeat. Quick and easy with just a couple of code lines and no extra buffer space needed. Also, the comparison code will terminate as soon as possible in case the strings where not identical - why convert the full string to lowercase if it was enough to look at the first character?
your code:
for (;i <= strlen(checkbody);i++) {}
will call strlen() once for every character in checkbody(). And strlen() will then have to step through every character in checkbody... For a 100-character string, the inner loop in strlen() will have to step 100*100 = 10000 times! No need for an O(n^2) solution to an O(n) problem. No need for a separate loop variable or knowing the length of the string. Since you are scanning through the string one character at the time anyway - just let the loop end when the current character is '\0'.
The lwrbuffer() function is converting the input string to lowercase in-place. So why are you at the same time assigning the lower-case conversion into the lowertextBody variable? Also note that the lowertextBody pointer has never been assigned an initial value, so it doesn't point to a buffer that can store any values.
You continue with even one more "extra" string copy, doing:
strcpy (lwrtext,lowertextBody);
But this time too, the lwrtext pointer hasn't been initialized, so there are no buffer to store the string.
I really, really recommend that you pick up a good book on C - you can't do embedded programming if you are not comfortable writing code on a PC.
Drop your over-complicated code and sit down a bit and think about implementing a stricmp() yourself. I have already mentioned the required steps in the algorithm. They are few. They are simple. So the stricmp() function must by deduction also be simple.