|
|
View previous topic :: View next topic |
Author |
Message |
Quinni
Joined: 24 Mar 2006 Posts: 1
|
Problem w. built-in function toupper (convert to uppercase) |
Posted: Fri Mar 24, 2006 11:21 am |
|
|
Hi,
Does anyone know why the line
strnew[i]=toupper(*ptr);
does not work? It works in every ANSI C-Compiler but not with the CCS-Compiler. Its a simple task converting a char to uppercase.
I have found the work around you can see below, but i would like to know why the specific line does not work.
This is only a code fragment - all pointers and variables are set correctly!
Thx for any answer.
Quinni
char c;
char * ptr;
This does NOT Work
strnew[i]=toupper(*ptr); // this line does not work as i expect
//convert to uppercase and store it in a new string
This Code works:
c=*ptr; //first store dereferenced pointer to c
strnew[i]=toupper(c); //convert c to uppercase and store it in new string |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Mar 24, 2006 12:39 pm |
|
|
..
Last edited by treitmey on Fri Mar 24, 2006 4:05 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 24, 2006 2:51 pm |
|
|
It looks like the problem occurs when the result from toupper()
is assigned to an array with a variable index. Look at the test
program shown below. It produces the results shown below. It's only
incorrect in the 2nd test. I tested this with PCM vs. 3.248 and 3.449.
Code: |
first result = 41
2nd result = 61 <-- incorrect
3rd result = 41
(Values are in Hex)
|
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
char *ptr;
char c;
char string[10] = {"a"};
char strnew[10];
int8 i;
ptr = string;
c = toupper(*ptr);
printf("first result = %x \n\r", c);
i = 0;
ptr = string;
strnew[i] = toupper(*ptr);
printf("2nd result = %x \n\r", strnew[0]);
ptr = string;
strnew[0] = toupper(*ptr);
printf("3rd result = %x \n\r", strnew[0]);
while(1);
} |
=======================
I don't have time to investigate this right now. I've got to
do some work at the company. But as a work-around you can
use the following replacement function for toupper(). I tested
it with the program above and it always works.
Code: |
char my_toupper(char c)
{
if(c >= 'a' && c <= 'z')
c -= 0x20;
return(c);
} |
|
|
|
Ttelmah Guest
|
|
Posted: Sat Mar 25, 2006 9:02 am |
|
|
Yes, it a definite bug.
If you look at the assembler generated, in the specific case of using a pointer reference on both sides of the equation (remember in C an array, and pointer are just two different constructs giving the same result), with a variable index on the left side, the code generates:
Code: |
.................... strnew[i] = (toupper(*ptr));
00BE: MOVLW 2D
00BF: ADDWF 37,W
00C0: MOVWF 38
00C1: MOVF 21,W
00C2: MOVWF 04
00C3: MOVF 00,W
00C4: MOVWF 39
00C5: SUBLW 60
00C6: BTFSC 03.0
00C7: GOTO 0CF
00C8: MOVF 39,W
00C9: SUBLW 7A
00CA: BTFSS 03.0
00CB: GOTO 0CF
00CC: MOVF 39,W
00CD: ANDLW DF //Correctly generates result
00CE: GOTO 0CF
00CF: MOVF 38,W //Uurgh, W is now destroyed
00D0: MOVWF 04
00D1: MOVF 39,W //Retreive the original value...
00D2: MOVWF 00 //and save this.
|
I'd report this, but in the meantime, probably use:
Code: |
#define toupper(x) ((x)>='a' && (x)<='z')?(x&0xDF):(x)
|
Which has the advantage of 'overwriting' the existing declaration, without having to change the rest of the code (though produces slightly bulkier code).
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
|