Search code examples
type-conversionfifofsmatoi

Type conversion - string of characters to integer


Hello I am writing my program in C, using PSoC tools to program my Cypress development kit. I am facing an issue regarding type conversion of a string of characters collected in my circular buffer (buffer) to a local variable "input_R", ultimately to a global variable st_input_R. The event in my FSM calling this action function is given below:


void st_state_5_event_0(void)   //S6 OR S4
{   
    char buffer[ST_NODE_LIMIT] = {0};
    st_copy_buffer(buffer);
    uint32 input_R = {0};
    mi_utoa(input_R, buffer);

    if ((input_R >= 19000) && (input_R <= 26000))
    {   
        st_input_R = input_R;
        _st_data.state = ST_STATE_6; 
    }
    else
    {
        _st_data.status = ST_STATE_4;
    }
    UART_1_Stop();

    st_stop();

    st_empty_buffer();
}  

ST_NODE_LIMIT = 64 st_copy_buffer copies the the numbers I type in using hyper terminal to the circular buffer named "buffer". input_R is the 32 bit integer I want the buffer content to be converted to. mi_utoa is the function I am using for converting the contents in the buffer to input_R and is detailed below:


uint8 mi_utoa(uint32 number, char *string)
{
    uint8 result = MI_BAD_ARGUMENT;

    if (string != NULL)
    {
        uint8 c = 0;
        uint8 i = 0;
        uint8 j = 0;

        do
        {
            string[i++] = number % 10 + '0';
        } while ((number /=10) > 0);

        string[i] = '\0';

        for (i = 0, j = strlen(string) - 1 ; i < j ; i++, j--)
        {
            c = string[i];
            string[i] = string[j];
            string[j] = c;
        }

        result = MI_SUCCESS;
    }

    return result;
}

The problem is, suppose if I enter 21500(+\r), the mi_utoa function converts the first digit to 0 the second digit to \000 while the other digits including the carriage return "\r" remains unaltered. As a result the input_R is NOT = 21500. Its happening for any string of digits I input. So the condition "if ((input_R >= 19000) && (input_R <= 26000))" is never satisfied. Hence the FSM returns to state 4 all the time and I am going in circles.

Can you please advice where the bug is in the mi_utoa function? Let me know if you want to know any other details.


Solution

  • Your function st_state_5_event_0() sets the value input_R to zero. Then you call mi_utoa(), which converts the value input_R to an ascii string, "0".

    void st_state_5_event_0(void)   //S6 OR S4
    {   
        char buffer[ST_NODE_LIMIT] = {0};
        //what is the value of buffer after this statement?
        st_copy_buffer(buffer);
        //the value of input_R after the next statement is =0
        uint32 input_R = {0};
        //conversion of input_R to string will give ="0"
        mi_utoa(input_R, buffer);
    
        if ((input_R >= 19000) && (input_R <= 26000))
        {   
            st_input_R = input_R;
            _st_data.state = ST_STATE_6; 
        }
        //...
    }
    

    You probably want a function which converts your ascii buffer to a number.

    uint8
    mi_atou(uint32* number, char *string)
    {
        uint8 result = MI_BAD_ARGUMENT;
    
        if (!string) return result;
        if (!number) return result;
        uint8 ndx = 0;
        uint32 accum=0;
        for( ndx=0; string[ndx]; ++ndx )
        {
            if( (string[ndx] >= '0') && (string[ndx] <= '9') )
            {
                accum = accum*10 + (string[ndx]-'0');
                //printf("[%d] %s -> %d\n",ndx,string,accum);
            }
            else break;
        }
        //printf("[%d] %s -> %d\n",ndx,string,accum);
        *number = accum;
        result = MI_SUCCESS;
        return result;
    }
    

    Which you would call by providing the address of the number to store the result,

        mi_atou(&input_R, buffer);