简体   繁体   中英

Converting from char* to int

My code fails and returns a really big number:

#include <stdio.h>

int main()
{
    char *s = "hello123";
    printf("%d\n",*(int *)s);
    return 0;
}

with atoi it returns 0, any ideas?

What im trying to achieve is: for example im sending "hello123" to a server software, the server software should get the "123" numeric in the string, doing this by this method:

uint16_t get_uint16(NetworkMessage *message)
{
    uint16_t ret = 0;
    if (!message || !message->buffer)
        return 0;

    ret = *(uint16_t *)(message->buffer + message->position);
    message->position += sizeof(uint16_t);
    return ret;
}

Your code doesn't do what you think it does. You can't convert text to a number and expect it to figure out what numbers you want.

A string is an array of characters, which each have an ASCII value. By casting to (int*) , it takes the ASCII value of the first 4 characters (4 bytes to an int) and creates one huge number out of it.

In your example, the ASCII values of the first 4 characters are { 0x68, 0x65, 0x6c, 0x6c } . Now you reverse the order for little endian systems to { 0x6c, 0x6c, 0x65, 0x68 } . You combine these into 0x6c6c6568 . Converting that to decimal is 1,819,043,176 . Which is the number you get in your output.

If you just want the 123 you have to use clever string parsing to parse out the hello , and then use atoi() on the remaining.

This assumes your string has two parts, the first indeces holding chars (eg hello ) and the last indeces holding the number (eg 123 ). From what I understand from your comments this is what you wanted to do.

#include <stdio.h>  
#include <stdlib.h>

int main() 
{
     char* s = "hello123";
     char* num_ptr = s;

     while(*num_ptr < '0' || *num_ptr > '9')
          ++num_ptr;

     int number = atoi(num_ptr);

     printf("%d\n", number);
     return 0; 
}

After edit : Try that? I assume message_buffer contains your message and is of type char*

int get_number(char* message_buffer)
{
     char* num_ptr = message_buffer + strlen(message_buffer) - 1;

     while(isdigit(num_ptr) && num_ptr > message_buffer)
          --num_ptr;

     int number = atoi(num_ptr);

     if(number > UINT16_RANGE)
          //Handle error here

     return number;     
}


uint16_t get_uint16(NetworkMessage *message) 
{
     uint16_t ret = 0;
     if (!message || !message->buffer)
         return 0;      

     ret = get_number(message->buffer);
     //message->position += sizeof(uint16_t);     
     return ret; 
} 

You need to use atoi(s) .

In your code, you are casting string pointer to integer pointer, reading first four bytes of a string as some large integer. int atoi(char*) will do a proper parsing, returning integer value.

Parsing "hello123" it will stop on first non numeric character, and return 0. You may skip non numeric characters, testing with int isdigit(char) :

int atoi_skip(char *s) {
        while(*s != '\0' && !isdigit(*s)) s++; /* skip non digits */
        return atoi(s);
}

Everyone else is absolutely right. You can't convert a character array to an integer by using a cast. It doesn't work that way. In C, chars are represented by integers. When you write:

char *s = "hello123";

What you're getting is an array with a bunch of characters in it. You could equivalently write:

char *s = {'h', 'e', 'l', 'l', 'o', '1', '2', '3', '\0'};

Thus, when you're calling printf("%d\\n",*(int *)s); , what you're doing is casting the memory address of your character array to a pointer to an integer. You're then taking the contents of this integer and printing that. I'm pretty sure the result you'll get will depend on the system you're using, but it's definitely not what you want.

What you probably want to do is this:

printf("%d\n", atoi(&(s[5]));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM