Thread: Problem with strtod

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6

    Question Problem with strtod

    Hi. I have been left some code by a previous design engineer which i need to compile. However when i try to compile the code it is giving the following warning:

    error C2371: 'strtod' : redefinition; different basic types
    c:\program files\microsoft visual studio\vc98\include\stdlib.h(309) : see declaration of 'strtod'

    The code is given below:-
    Code:
    float strtod(char *s,char *endptr) {
       float pow10 = 1.0;
       float result = 0.0;
       int sign = 0, point = 0;
       char c;
       int ptr = 0;
    
       if(s)
       {
          c=s[ptr++];
       }
    
       while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
          if(c == '-') {
             sign = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 0) {
             result = 10*result + c - '0';
             c = s[ptr++];
          }
    
          if (c == '.') {
             point = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 1) {
             pow10 = pow10*10;
             result += (c - '0')/pow10;
             c = s[ptr++];
          }
          
          if (c == '+') {
             c = s[ptr++];
          }
       }
    
       if (sign == 1)
          result = -1*result;
       if(endptr)
       {
          if (ptr) {
             ptr--;
             *((char *)endptr)=s+ptr;
          }
          else
             *((char *)endptr)=s;
       }
    
       return(result);
    }
    Does anybody have any idea what is wrong? Thanks

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, considering strtod is a standard function that returns a double, re-implementing it as a function that returns float would give that sort of problem.

    endptr should also be char **, eliminating the ugly casting about that is done in the bottom bit of the function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6
    Hi tried the above and i am now getting the error message warning C4047: '=' : 'const char ' differs in levels of indirection from 'const char *'

    Code:
    double strtod(const char *s,char **endptr) {
       double pow10 = 1.0;
       double result = 0.0;
       int sign = 0, point = 0;
       char c;
       int ptr = 0;
    
       if(s)
       {
          c=s[ptr++];
       }
    
       while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
          if(c == '-') {
             sign = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 0) {
             result = 10*result + c - '0';
             c = s[ptr++];
          }
    
          if (c == '.') {
             point = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 1) {
             pow10 = pow10*10;
             result += (c - '0')/pow10;
             c = s[ptr++];
          }
          
          if (c == '+') {
             c = s[ptr++];
          }
       }
    
       if (sign == 1)
          result = -1*result;
       if(endptr)
       {
          if (ptr) {
             ptr--;
             *((const char *)endptr)=s+ptr;
          }
          else
             *((const char *)endptr)=s;
       }
    
       return(result);
    }

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
             *((const char *)endptr)=s+ptr;
    should probably be:
    Code:
             *endptr=s+ptr;
    (And likewise on the next line).

    If you indicate which line you get that error message on, perhaps it would help.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6
    Hi Thanks, i tried that - looks like we are getting somewhere, however, the error now is:-

    warning C4090: '=' : different 'const' qualifiers

    for both the new lines added (i.e. *endptr=s+ptr; and
    *endptr=s

    Code:
    double strtod(const char *s,char **endptr) {
       float pow10 = 1.0;
       float result = 0.0;
       int sign = 0, point = 0;
       char c;
       int ptr = 0;
    
       if(s)
       {
          c=s[ptr++];
       }
    
       while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
          if(c == '-') {
             sign = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 0) {
             result = 10*result + c - '0';
             c = s[ptr++];
          }
    
          if (c == '.') {
             point = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 1) {
             pow10 = pow10*10;
             result += (c - '0')/pow10;
             c = s[ptr++];
          }
          
          if (c == '+') {
             c = s[ptr++];
          }
       }
    
       if (sign == 1)
          result = -1*result;
       if(endptr)
       {
          if (ptr) {
             ptr--;
    		 *endptr=s+ptr;
          }
          else
    		 *endptr=s;
       }
    
       return(result);
    }

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, I think (cheating and looking at glibc's implementation, which is about 100 times more complex than yours) that you need a cast on the endptr assignment:
    Code:
       *endptr = (char *)s+ptr;
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6

    Wink

    Hi. Thats brilliant, no problems have shown up now for this part of the code. Many Thanks!!

    When i try to compile in MPLAB it is bringing up a problem with the string.h file :

    It says: >>> Warning 201 "C:\PROGRA~1\PICC\drivers\string.h" Line 88(1,1): Assignment inside relational expresion

    this is the code it is referring to:

    Code:
    /* standard template: char *strcat(char *s1, const char *s2)
    appends s2 to s1*/
    
    char *strcat(char *s1, char *s2)
    {
       char *s;
    
       for (s = s1; *s != '\0'; s++);
       while ((*s = *s2) != '\0')
     //>line error is pointing at  {
           s++;
           s2++;
       }
       return(s1);
    }
    why would it be saying there is a problem with a standard library function?

    Thanks!

  8. #8
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6
    I have managed to get rid of the warning message by disabling warning messages, however, during the build using MPLAB with CCsC compiler it is giving these error messages relating to the code i have just modified :

    *** Error 32 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(21,26): Expecting a , or )
    *** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(26,27): Expecting a declaration
    *** Error 48 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(27,28): Expecting a (
    *** Error 36 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(36,42): Expecting a ; or ,
    *** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(44,45): Expecting a declaration
    *** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(4,6): Expecting a declaration
    *** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(6,7): Expecting a declaration
    *** Error 48 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(7,8): Expecting a (
    etc etc

    Why would it be expecting a "(" or ","
    Is there any way to ignor these messages - i just want to get the hex file to blow onto the chip?

    Code:
    double strtod(const char *s,char **endptr) {
       float pow10 = 1.0;
       float result = 0.0;
       int sign = 0, point = 0;
    Any Thoughts?

  9. #9
    Registered User
    Join Date
    Nov 2008
    Location
    england
    Posts
    6
    here is the full code incase i am missing any thing?

    Code:
    #include <16f876.h>
    #include <stdlib.h>
    #include <math.h>
    #use delay (CLOCK = 4000000)
    #use RS232 (BAUD = 9600,parity = n, bits = 8, xmit=PIN_c6, rcv = PIN_c7, ERRORS)
    #use fixed_io (b_outputs=PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B7)
    #use fixed_io (a_outputs=PIN_A5)
    #define RELAY_A PIN_B0
    #define RELAY_B PIN_B1
    #define INC PIN_B2
    #define UD PIN_B3
    #define CS PIN_B4
    #define A_B_SELECT PIN_B5
    #define START_UP PIN_B6
    #define BUZZER PIN_B7
    #define LED PIN_A5
    
    // Test Limits
    #define TARGET_VALUE 0.320
    #define VARIANCE1 -0.01
    #define VARIANCE2 0.01
    
    
    double strtod(const char *s,char **endptr) {
       float pow10 = 1.0;
       float result = 0.0;
       int sign = 0, point = 0;
       char c;
       int ptr = 0;
    
       if(s)
       {
          c=s[ptr++];
       }
    
       while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
          if(c == '-') {
             sign = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 0) {
             result = 10*result + c - '0';
             c = s[ptr++];
          }
    
          if (c == '.') {
             point = 1;
             c = s[ptr++];
          }
    
          while((c >= '0' && c <= '9') && point == 1) {
             pow10 = pow10*10;
             result += (c - '0')/pow10;
             c = s[ptr++];
          }
          
          if (c == '+') {
             c = s[ptr++];
          }
       }
    
       if (sign == 1)
          result = -1*result;
       if(endptr)
       {
          if (ptr) {
             ptr--;
    		 *endptr = (char *)s+ptr;
    		 //*endptr=s+ptr;
             //*((const char *)endptr)=s+ptr;
          }
          else
    		 *endptr = (char *)s;
    		 //*endptr=s;
             //*((const char *)endptr)=s;
       }
    
       return(result);
    }   
    
    void select_relay()
    {
    	output_low (RELAY_A);
    	output_low (RELAY_B);
    	if (input(A_B_SELECT))
    		output_high (RELAY_B);
    	else
    		output_high (RELAY_A);
    	delay_us (10);
    }
    
    void set_up_digilux()
    {
    	putc('M');
    	delay_ms(5);
    	putc('B');
    	delay_ms(5);
    	putc(' ');
    	delay_ms(5);
    	putc('2');
    	delay_ms(5);
    	putc(13);
    	delay_ms(10);
    }	
    
    
    
    void increment_intensity()
    {
    	output_high (CS);
    	output_low (UD);
    	output_low (INC);
    	delay_ms (50);
    	output_high (INC);
    	delay_ms (50);
    	output_low (INC);
    }
    
    void decrement_intensity()
    {
    	output_high (CS);
    	output_high (UD);
    	output_low (inc);
    	delay_ms (50);
    	output_high (INC);
    	delay_ms (50);
    	output_low (INC);
    }
    
    void store_pot_value()
    {
    	output_high (CS);
    	output_low (INC);
    	delay_ms (100);
    	output_low (CS);
    }
    
    
    
    void main()
    {
    	float result;
    	char a;
    	char b;
    	char incoming[50];
    	char *ptr2;
    	char *ptr = 0;
    	float mantissa;
    	char error_read;
    
    	float measurement;
    	unsigned int exit_loop =0;
    	char count;
    	output_low (RELAY_A);
    	output_low (RELAY_B);
    	output_low (BUZZER);
    	output_low (LED);
    	
    	do
    	{
    	select_relay();
    	exit_loop = 0;
    	delay_ms(2000);
    	delay_ms(2000);
    	delay_ms(2000);
    	
    	set_up_digilux();
    	
    	delay_ms(1000);
    
    
    
    
    		do
    		{
    
    			do
    			{
    				putc('S');
    				delay_ms(5);
    				putc('T');
    				putc(13);
    				//	delay_ms(5);
    				a=0;
    				b=0;
    		
    				do 
    				{
    					a=getch();
    					incoming[b++] = a;
    				} while (a !=13 & b<40);
    				error_read = (incoming[19] - 0x30);
    				
    			}while((incoming[1] != 'S' && incoming [2] != 'T') || bit_set(error_read,0));
    		
    	
    			ptr2 = incoming + 4;
    			result = strtod(ptr2,&ptr);
    		
    			a = (incoming[12] - 0x30) * 10;
    			a += (incoming[13] - 0x30);
    		
    			mantissa = pow(10,a);
    
    			if (incoming[11] == '-')
    				result /= mantissa;
    			else 
    				result *= mantissa;
    
    //			read_measurement(measurement);
    			measurement = 0;
    			measurement = result - TARGET_VALUE;
    
    			if(measurement < VARIANCE1)
    				increment_intensity();
    
    
    			else if(measurement > VARIANCE2)
    				decrement_intensity();
    			
    			else
    				do 
    				{
    					delay_ms(40000);
    					do
    					{
    						do
    						{
    							putc('S');
    							delay_ms(5);
    							putc('T');
    							putc(13);
    							//	delay_ms(5);
    							a=0;
    							b=0;
    					
    							do 
    							{
    								a=getch();
    								incoming[b++] = a;
    							} while (a !=13 & b<40);
    							error_read = (incoming[19] - 0x30);
    						}while((incoming[1] != 'S' && incoming [2] != 'T') || bit_set(error_read,0));
    		
    	
    						ptr2 = incoming + 4;
    						result = strtod(ptr2,&ptr);
    			
    						a = (incoming[12] - 0x30) * 10;
    						a += (incoming[13] - 0x30);
    		
    						mantissa = pow(10,a);
    	
    						if (incoming[11] == '-')
    							result /= mantissa;
    						else 
    							result *= mantissa;
    						measurement = 0;
    						measurement = result - TARGET_VALUE;
    //						read_measurement(measurement);
    						if (measurement < VARIANCE1)
    							increment_intensity();
    						
    						else if (measurement > VARIANCE2)
    							decrement_intensity();
    						else
    							exit_loop = true;
    							
    						if(abs(measurement) > 0.1)
    							delay_ms(200);
    						else if (abs(measurement) > 0.05)
    							delay_ms(500);
    						else 
    							delay_ms(1000);
    							
    					}while (!exit_loop);
    			
    			}while (!exit_loop);
    			if(abs(measurement) > 0.1)
    				delay_ms(200);
    			else if (abs(measurement) > 0.05)
    				delay_ms(500);
    			else 
    				delay_ms(1000);
    			
    		}while (!exit_loop);
    	
    		exit_loop = 0;
    
    		
    		store_pot_value();
    		count = 0;
    		do 
    		{
    			output_high (BUZZER);
    			delay_ms(25);
    			output_low (BUZZER);
    			delay_ms(100);
    			count = count + 1;
    		} while (count < 6);	
    		output_high (LED);
    		do
    		{
    			output_low (RELAY_A);
    			output_low (RELAY_B);
    		}while (input(START_UP));		
    
    
    
    
    	}while (!input(START_UP));
    }

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you sure you closed your previous function (matched all the curly braces)? It looks as though the compiler is looking for a function call, not a function definition. Edit: Now that you've posted code, that's obviously right out. It doesn't appear to me to have any problems that I can see right off. Edit edit: Surely your compiler doesn't require the old K&R-style function signatures, with just the names in the parentheses and then the types later?
    Last edited by tabstop; 11-03-2008 at 09:59 AM.

  11. #11
    Hacker MeTh0Dz's Avatar
    Join Date
    Oct 2008
    Posts
    111
    What compiler are you using?

    Edit....... I see you said above.....

    Well I am checking out their site and apparently some of their compilers do in fact use K&R syntax.

    Example -> http://www.ccsinfo.com/content.php?page=sxcoverview
    Last edited by MeTh0Dz; 11-03-2008 at 11:06 AM.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It is possible that they require K&R syntax, but also possible that the support for double (which may be why it was defined with non-standard syntax).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM