2011-04-05 5 views
3

Mon code échoue et renvoie un nombre vraiment grand:Conversion de char * en int

#include <stdio.h> 

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

avec atoi elle retourne 0, des idées?

Quelle im essayant d'obtenir est: par exemple im envoyer « hello123 » à un logiciel serveur, le logiciel serveur doit obtenir le numérique « 123 » dans la chaîne, faisant par cette méthode:

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; 
} 
+0

ce que vous en train d'essayer d'accomplir? –

+0

Quelle sortie attendez-vous ??? – Macmade

+0

pourquoi utiliser '* (int *) s'? Explique le. –

Répondre

3

Cela suppose que votre chaîne comporte deux parties, les premiers caractères de maintien des pièces (par exemple hello) et les dernières pièces contenant le numéro (par exemple 123). D'après ce que je comprends de vos commentaires, c'est ce que vous vouliez faire.

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

Après edit: Essayez ça? Je suppose que message_buffer contient votre message et est de 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; 
} 
+0

@ Muggen: renvoie 0: S –

+0

@Fallen, quel est le contenu exact de 'message-> buffer'? – Muggen

+0

@Muggen: "hello123" –

0

Vous devez utiliser atoi(s).

Dans votre code, vous lancez le pointeur de chaîne au pointeur entier, en lisant les quatre premiers octets d'une chaîne sous la forme d'un grand nombre entier. int atoi(char*) fera une analyse correcte, renvoyant la valeur entière.

Parsing « hello123 » il arrêtera le premier caractère non numérique, et retourner 0. Vous pouvez sauter des caractères non numériques, des tests avec int isdigit(char):

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

Cest wut je l'ai dit dans le message principal ... –

3

Votre code ne fait pas ce que vous pensez qu'elle . Vous ne pouvez pas convertir le texte en nombre et vous attendre à trouver les chiffres que vous voulez.

Une chaîne est un tableau de caractères, chacun ayant une valeur ASCII. En convertissant à (int*), il prend la valeur ASCII des 4 premiers caractères (4 octets à un int) et en crée un énorme nombre. Dans votre exemple, les valeurs ASCII des 4 premiers caractères sont { 0x68, 0x65, 0x6c, 0x6c }. Maintenant, vous inversez la commande pour les systèmes little endian à { 0x6c, 0x6c, 0x65, 0x68 }. Vous combinez ceux-ci en 0x6c6c6568. La conversion en décimal est 1,819,043,176. Quel est le nombre que vous obtenez dans votre sortie.

Si vous voulez juste le 123 vous devez utiliser l'analyse syntaxique de chaîne intelligente pour analyser le hello, puis utilisez atoi() sur le reste.

+0

Ive ajouté plus d'informations à la poste principale, consultez-le –

0

Tout le monde est tout à fait raison. Vous ne pouvez pas convertir un tableau de caractères en nombre entier en utilisant un transtypage. Cela ne fonctionne pas comme ça. En C, les caractères sont représentés par des entiers. Lorsque vous écrivez:

char *s = "hello123"; 

Ce que vous obtenez est un tableau avec un tas de caractères. Vous pouvez écrire de façon équivalente:

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

Ainsi, lorsque vous appelez printf("%d\n",*(int *)s);, ce que vous faites est coulée l'adresse mémoire de votre tableau de caractères à un pointeur sur un entier.Vous prenez alors le contenu de cet entier et l'imprimez. Je suis sûr que le résultat que vous obtiendrez dépendra du système que vous utilisez, mais ce n'est certainement pas ce que vous voulez.

Qu'est-ce que vous voulez sans doute faire est la suivante:

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