2015-03-22 2 views
0

Я хочу разбить строку на «\ n», проанализировать токен и сохранить некоторые значения в структуре.Не могу понять это поведение strtok и sscanf

Вот фактический код:

typedef struct { 
    char *address; 
    int port; 
    unsigned int nodeId; 
} node; 

... 

node *ft = malloc(32 * sizeof(node)); 

... 

int function (char *addr, int port, node * ft) { 
    char request[BUFSIZE], answer[8192]; 
    char *token; 
    int c = 0; 

    snprintf(request, sizeof(request), "Keyword"); 
    request(addr, port, request, answer); 

    printf("answer at this point is:\n%s\n", answer); 
    memset(&token, '\0', sizeof(token)); 

    token = strtok(answer, "\n"); 
    while (token != NULL) { 
     printf("c = %d\n", c); 
     printf("Token:\n%s\n", token); 
     printf("Token addr:%p\n", &token); 
     sscanf(token, 
       "nodeId:%u nodeAddress:%s nodePort:%d", 
       &ft[c].nodeId, ft[c].address, &ft[c].port); 
     printf("id: %u\n", ft[c].nodeId); 
     printf("addr: %s\n", ft[c].address); 
     printf("port: %d\n", ft[c].port); 
     token = strtok(NULL, "\n"); 
     printf("Token after:\n%s\n", token); 
     printf("==========================\n"); 
     c++; 
    } 
    return c; 
} 

Выход следующий:

answer at this point is: 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

c = 0 

Token: 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

Token addr:0x7fff05bac308 

id: 65228883 

addr: 127.0.0.1 

port: 3081 

Token after: 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

========================== 

c = 1 

Token: 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

Token addr:0x7fff05bac308 

id: 65228883 

addr: (null) 

port: 0 

Token apres: 

nodeId:65228883 nodeAddress:127.0.0.1 nodePort:3081 

... 

Как вы можете видеть, первая линия правильно положить в структуры, но со 2-го итерация, даже если токен установлен на следующую строку и, кажется, имеет правильный контент, устанавливается только первый элемент структуры (nodeId), но не два других.

Я считаю, что мое отсутствие понимания strtok/sscanf может быть задействовано здесь.

Спасибо!

EDIT: здесь находится mvce. При этом даже первый токен не корректно обрабатывается sscanf. Это может быть с «% s» Я пытаюсь установить с адресом внутрибрюшинно ..

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

int main() { 
    char answer[8192] = "nodeId:107813116 nodeAddress:10.190.233.184 nodePort:3081\nnodeId:107813116 nodeAddress:10.190.233.184 nodePort:3081\nnodeId:107813116 nodeAddress:10.190.233.184 nodePort:3081\nnodeId:107813116 nodeAddress:10.190.233.184 nodePort:3081\nnodeId:107813116 nodeAddress:10.190.233.184 nodePort:3081"; 
    const char s[2] = "\n"; 
    char *token; 

    typedef struct { 
     char *address; 
     int port; 
     unsigned int nodeId; 
    } node; 

    node * ft = malloc(32 * sizeof(node)); 

    /* get the first token */ 
    token = strtok(answer, s); 

    int c = 0; 
    /* walk through other tokens */ 
    while (token != NULL) { 
     printf("c = %d\n", c); 
     printf("Token:\n%s\n", token); 
     printf("Token addr:%p\n", &token); 
     sscanf(token, 
       "nodeId:%u nodeAddress:%s nodePort:%d", 
       &ft[c].nodeId, ft[c].address, &ft[c].port); 
     printf("id: %u\n", ft[c].nodeId); 
     printf("addr: %s\n", ft[c].address); 
     printf("port: %d\n", ft[c].port); 
     token = strtok(NULL, "\n"); 
     printf("Token after:\n%s\n", token);                                          
     printf("==========================\n"); 
     c++; 
    } 

    return(0); 
} 
+0

Просьба показать декларацию 'ft []' –

+0

, что бы 'printf (« Token addr:% p \ n », токен);' print? – dvhh

+0

узел @WeatherVane * succFt = malloc (32 * sizeof (node)); – Bacon

ответ

2

Вы выделили память для struct массива, как этот

node *ft = malloc(32 * sizeof(node)); 

, но вы не имеете инициализируется каждый элемент struct, каждый из которых имеет указатель на строку, которая не была выделена никакой памяти. Затем вы передаете этот неинициализированный указатель строки как аргумент %s в scanf(), что приведет к неопределенному поведению. Если вам повезет, это работает, когда указатель строки только что произойдет, чтобы указать на память, которой вы владеете, которая не коррумпирует что-либо еще.

Я не могу объяснить, почему ft[1].port было напечатано 0 но вы редактировали выход, поэтому он не может доверять, чтобы быть вашим фактический выход. (он говорит «apres» вместо «after»).

+0

Я проверяю это прямо сейчас. вещь «apres/after» была просто переводом, не связанным с другими модификациями. – Bacon

Смежные вопросы