简体   繁体   English

从char *转换为int

[英]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? 与atoi它返回0,任何想法?

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: 我试图实现的是:例如我发送“hello123”到服务器软件,服务器软件应该在字符串中得到“123”数字,通过这种方法做到这一点:

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. 字符串是一个字符数组,每个字符都有一个ASCII值。 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. 通过转换为(int*) ,它获取前4个字符的ASCII值(4个字节为int)并从中创建一个巨大的数字。

In your example, the ASCII values of the first 4 characters are { 0x68, 0x65, 0x6c, 0x6c } . 在您的示例中,前4个字符的ASCII值为{ 0x68, 0x65, 0x6c, 0x6c } Now you reverse the order for little endian systems to { 0x6c, 0x6c, 0x65, 0x68 } . 现在,您将小端系统的顺序反转为{ 0x6c, 0x6c, 0x65, 0x68 } You combine these into 0x6c6c6568 . 您将这些组合成0x6c6c6568 Converting that to decimal is 1,819,043,176 . 将其转换为十进制是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. 如果你只是想要123你必须使用聪明的字符串解析来解析hello ,然后在剩下的上使用atoi()

This assumes your string has two parts, the first indeces holding chars (eg hello ) and the last indeces holding the number (eg 123 ). 这假设你的字符串有两个部分,第一个持有字符的indeces(例如hello )和持有数字的最后一个indeces(例如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* 我假设message_buffer包含你的消息,其类型为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) . 你需要使用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. int atoi(char*)将进行正确的解析,返回整数值。

Parsing "hello123" it will stop on first non numeric character, and return 0. You may skip non numeric characters, testing with int isdigit(char) : 解析“hello123”它将在第一个非数字字符上停止,并返回0.您可以跳过非数字字符,使用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. 在C中,字符由整数表示。 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); 因此,当你调用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]));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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