char buffer[1000];
recv(sock, buffer, sizeof(buffer), 0);
char *ptr;
printf("\n%s\n", buffer);
char searchPos[500];
sprintf(searchPos, "mercenary %d position", ID);
char *req = strstr(buffer, searchPos);
if(req != NULL)
{
char *token;
token = strtok_r(buffer, " ", &ptr);
token = strtok_r(ptr, " ", &ptr);
token = strtok_r(ptr, " ", &ptr);
token = strtok_r(ptr, " ", &ptr);
printf("%s\n",token);
}我有这样的代码,在printf行产生分段错误,但我不知道原因。缓冲区看起来像是“雇佣兵2号阵地15 20”。有人能帮我吗?
发布于 2018-04-07 15:39:46
有几个地方可能会出问题--我们不能直接告诉你出了什么问题。
recv()返回“接收到的字节数,或者-1 (如果发生错误)”--您无法知道这里是否出错(除非检查返回值)。此外,recv()不会终止“字符串”,因为就它所知/关心的而言,它只是数据。
sprintf()会写到缓冲区中,而不考虑它的长度--除非您能够保证有足够的空间,否则不要使用它。使用snprintf(),这将尊重缓冲区的长度。此外,检查返回值的潜在问题。但是,您的500 X char缓冲区确实非常大。
我很高兴看到你在使用strtok_r(),而不是strtok()。根据这个无关的Linux (非C)引用的说法,你使用它是错误的,但是你的使用本身不应该真的造成问题。
在第一次调用
strtok_r()时,str应该指向要解析的字符串,忽略saveptr的值。在后续调用中,str应该是空,而saveptr应该是自上次调用以来不变的。strtok()和strtok_r()函数返回指向下一个令牌的指针,即或NULL,如果没有更多的令牌。
最后,由于以下问题之一,printf()可能导致SEGFAULT:
token为空token并没有被终止,因此printf()遇到了杂草。我将押注于#1,否则您应该在第一个printf("\n%s\n", buffer);上看到一个SEGFAULT。我说“应该”,因为此时你可能会幸运地打印“隐形”垃圾。
发布于 2018-04-07 15:26:25
strtok_r,如果找到令牌,则指向令牌开头的指针。否则,为空指针。当被扫描的字符串(即空字符)的末端到达时,总是返回空指针。
char buffer[1000];
// make sure all bytes are initialized to 0
memset(buffer, '\0', sizeof(buffer));
// make sure there is at least one byte left that's set to 0
if( recv(sock, buffer, sizeof(buffer) - 1, 0) == -1 ) {
perror("recv()");
exit(1);
}recv不会在字符串的末尾放置一个空终止符(而printf %s则假定有一个)。
发布于 2018-04-08 08:38:01
我真的不知道是怎么回事。我试过另一个IDE,它成功了。谢谢你的帮助。
https://stackoverflow.com/questions/49708821
复制相似问题