Преобразование из char * в int - PullRequest
3 голосов
/ 05 апреля 2011

Мой код дает сбой и возвращает действительно большое число:

#include <stdio.h>

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

с atoi возвращает 0, есть идеи?

То, чего я пытаюсь достичь, это: например, я посылаю «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;
}

Ответы [ 4 ]

3 голосов
/ 05 апреля 2011

Ваш код не делает то, что вы думаете, что он делает.Вы не можете преобразовать текст в число и ожидать, что он выяснит, какие цифры вам нужны.

Строка - это массив символов, каждый из которых имеет значение ASCII.При приведении к (int*) он принимает значение ASCII первых 4 символов (4 байта до целого) и создает из него одно огромное число.

В вашем примере значения ASCII первых 4символы { 0x68, 0x65, 0x6c, 0x6c }.Теперь вы измените порядок для систем с прямым порядком байтов на { 0x6c, 0x6c, 0x65, 0x68 }.Вы объединяете их в 0x6c6c6568.Преобразование в десятичное значение 1,819,043,176.Какое число вы получите в своих выходных данных.

Если вы просто хотите, чтобы 123 вы использовали умный разбор строк, чтобы разобрать hello, а затем использовать atoi() для остальных.

3 голосов
/ 05 апреля 2011

Предполагается, что ваша строка состоит из двух частей: первая инденса, содержащая символы (например, hello), и последние индекси, содержащие число (например, 123). Из того, что я понимаю из ваших комментариев, это то, что вы хотели сделать.

#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; 
}

После редактирования: попробовать? Я предполагаю, что 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; 
} 
0 голосов
/ 05 апреля 2011

Все остальные абсолютно правы.Вы не можете преобразовать массив символов в целое число, используя приведение.Это не работает таким образом.В C символы представлены целыми числами.Когда вы пишете:

char *s = "hello123";

Вы получаете массив с кучей символов в нем.Вы могли бы эквивалентно написать:

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

Таким образом, когда вы вызываете printf("%d\n",*(int *)s);, то, что вы делаете, это приведение адреса памяти вашего массива символов к указателю на целое число.Затем вы берете содержимое этого целого числа и печатаете его.Я почти уверен, что результат, который вы получите, будет зависеть от системы, которую вы используете, но это определенно не то, что вы хотите.

То, что вы, вероятно, хотите сделать, это:

printf("%d\n", atoi(&(s[5]));
0 голосов
/ 05 апреля 2011

Вам нужно использовать atoi(s).

В вашем коде вы приводите строковый указатель к целочисленному указателю, читая первые четыре байта строки как большое целое число. int atoi(char*) выполнит правильный анализ, вернув целочисленное значение.

При анализе "hello123" он остановится на первом нечисловом символе и вернет 0. Вы можете пропустить нечисловые символы, тестируя с помощью int isdigit(char):

int atoi_skip(char *s) {
        while(*s != '\0' && !isdigit(*s)) s++; /* skip non digits */
        return atoi(s);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...