Can';我不理解strtok和sscanf的这种行为

Can';我不理解strtok和sscanf的这种行为,c,strtok,scanf,C,Strtok,Scanf,我想拆分“\n”上的字符串,解析令牌,并在结构中存储一些值 以下是实际代码: 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], an

我想拆分“\n”上的字符串,解析令牌,并在结构中存储一些值

以下是实际代码:

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

...
如您所见,第一行被正确地放入结构中,但是从第二次迭代开始,即使令牌被设置为下一行并且似乎具有正确的内容,也只设置了结构的第一个元素(nodeId),而没有设置其他两个元素

我相信我对strtok/sscanf的理解不足可能与此有关

谢谢

编辑:这是一个mvce。因此,即使第一个令牌也不能被sscanf正确解析。这可能必须与我试图用ip地址设置的“%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);
}
#包括
#包括
#包括
int main(){
字符回答[8192]=“节点ID:107813116节点地址:10.190.233.184节点地址:3081\n节点ID:107813116节点地址:10.190.233.184节点地址:3081\n节点ID:107813116节点地址:10.190.233.184节点地址:3081\n节点ID:107813116节点地址:10.190.233.184节点地址:3081\n节点ID:107813116节点地址:10.190.233.184节点地址:3081”;
常量字符s[2]=“\n”;
字符*令牌;
类型定义结构{
字符*地址;
国际港口;
无符号整数节点ID;
}节点;
node*ft=malloc(32*sizeof(node));
/*获取第一个令牌*/
令牌=strtok(答案,s);
int c=0;
/*浏览其他代币*/
while(令牌!=NULL){
printf(“c=%d\n”,c);
printf(“令牌:\n%s\n”,令牌);
printf(“令牌地址:%p\n”,&Token);
sscanf(代币,
“节点ID:%u节点地址:%s节点端口:%d”,
&ft[c].节点ID,ft[c].地址,&ft[c].端口);
printf(“id:%u\n”,ft[c].nodeId);
printf(“地址:%s\n”,ft[c]。地址);
printf(“端口:%d\n”,ft[c]。端口);
令牌=strtok(空,“\n”);
printf(“在:\n%s\n之后的令牌”,令牌);
printf(“===========================================\n”);
C++;
}   
返回(0);
}

您为
结构
数组分配了如下内存

node *ft = malloc(32 * sizeof(node));
但是您没有初始化每个
结构
元素,每个元素都有一个指向未分配任何内存的字符串的指针。然后将此未初始化的字符串指针作为
%s
参数传递给
scanf()
,这将导致未定义的行为。如果幸运的话,当字符串指针恰好指向您拥有的内存时,它就会工作,而您拥有的内存不会损坏其他任何东西


我无法解释为什么
ft[1]。端口
打印为
0
,但您已经编辑了输出,因此不能相信它是您的实际输出。(上面写的是“apres”而不是“after”)。

请显示
ft[]
什么将
printf(“令牌地址:%p\n”,令牌)的声明打印?@WeatherVane node*succFt=malloc(32*sizeof(node))@dvhh它会打印令牌指向的地址,所以它不会改变似乎是合法的。我错了吗?这不是你真正的密码<代码>请求(地址、端口、请求、应答)无法编译,因为
请求
不是函数<代码>英尺
从未定义,等等。请发封邮件,我正在查。“apres/after”只是一个翻译,不涉及其他修改。