'Why number x is added only to the first number of a double digit unsigned?

I'm working on a TCP server using an ARM and i want to open the payload and add a number. My code for doing that is seen below:

unsigned rcv_buff;
unsigned *ptr = malloc(sizeof(*ptr));
unsigned *out_ptr;

out_ptr = &rcv_buff;
memcpy(ptr, p->payload, p->len);
rcv_buff = *ptr + 1;

/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p->len) {
    err = tcp_write(tpcb, out_ptr, p->len, 1);
    free(ptr);


} else
    xil_printf("no space in tcp_sndbuf\n\r");`

For 1 to 9 it works fine, but when i send 10 it send back ":". For double digit number, the 1 is added only to the first number. For example, when i send 23 it sends back 33.



Solution 1:[1]

Why number x is added only to the first number of a double digit unsigned?

All the signs point to the payload being a text representation of a number, as @EugeneSh. diagnosed in comments. In that case, you probably want to convert that to an actual number before performing arithmetic on it. Since it seems that you want to reply with a text representation of the result, you will also need to convert back.

Because the usual conversion functions work on strings, but there is no evidence that the message body itself provides a string terminator after the last digit, you probably want to copy the payload into a long-enough character array in order to work with it. That will also be useful for the back-conversion of the result.

// large enough for a representation of any 32-bit unsigned number as a decimal string:
char text[11] = {0};  // the array is initially zero-filled
int digits = 0;

if (p->len <= 0 || p->len >= sizeof text) {
    // handle invalid-length payload ...
} else if (!isdigit((unsigned char) *p->payload)) {
    // handle invalid payload starting with a non-digit ...
} else {
    // Copy the payload to a separate buffer so that we can ensure a string terminator
    memcpy(text, p->payload, p->len);
    // the needed terminator is already present from the initialization of 'text'

    // Parse the payload as an unsigned integer
    char *end;
    unsigned num = strtoul(text, &end, 10);  // possible overflow; ignored
    if (*end != '\0') {
       // handle payload containing non-digits ...
    }

    // Write a text representation of the number plus one; assumes that the
    // 'text' array is long enough to accommodate all possible `unsigned` values.
    digits = snprintf(text, sizeof text, "%u", num + 1);
    assert(digits < sizeof text);  // fails only if text wasn't long enough after all
    assert(0 < digits); // fails on output error, which should not happen for snprintf
}

The updated result is left in text, and the number of decimal digits (== the number of characters written to text, exclusive of the null terminator) is left in digits. Note well that digits may exceed p->len, such as when the input was "9" or "99".

I leave it to you to prepare and send a response message containing the updated number.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Bollinger