Can';我不理解strtok和sscanf的这种行为
我想拆分“\n”上的字符串,解析令牌,并在结构中存储一些值 以下是实际代码: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
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”只是一个翻译,不涉及其他修改。