我正在编写FTP服务器,我需要以下列格式从输入字符串缓冲区解析远程服务器的ip和端口:
xxx,xxx,xxx,xxx,yyy,zzz
其中:
xxx
代表十进制的ip地址八位字节yyy
是圆形的((远程端口号)/ 256)zzz
是(远程端口号)%256 例如:127,0,0,1,123,64
表示ip = 127.0.0.1
和port = 31552
。
我目前正在使用sscanf
从输入字符串缓冲区中提取以下字段:
sscanf(str, "%u,%u,%u,%u,%u,%u", ret_ip, &ip[0], &ip[1], &ip[2], &temp1, &temp2) == 6
其中:
uint32_t
uint32_t
unsigned short int
示例代码:
#include <stdio.h>
#include <netdb.h>
int main(int argc, char *argv[])
{
uint32_t ip[4];
unsigned short int temp, temp1;
if (sscanf("127,0,0,1,142,214", "%u,%u,%u,%u,%u,%u", &ip[0], &ip[1], &ip[2], &ip[3], &temp, &temp1) == 6)
{
printf("%u : %u", temp, temp1);
}
return (0);
}
我的问题是,对于有效字符串, temp1 的值始终为0(零),即除了 temp1 之外,所有其他变量都根据字符串填充。我将不胜感激任何帮助。
答案 0 :(得分:4)
scanf
并不像printf
那样宽容格式说明符不匹配。说明符需要完全匹配,否则您调用未定义的行为。
unsigned short
使用%hu
。 %u
适用于unsigned int
。
uint32_t
等类型没有直接的格式说明符。您需要use a macro from inttypes.h
:"%" SCNu32
。
所有在一起:
if (sscanf(str, "%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%hu,%hu", ret_ip, &ip[0], &ip[1], &ip[2], &temp1, &temp2) == 6)
答案 1 :(得分:1)
与可用答案相比,以下内容添加到此答案中:
unsigned char
,然后将其存储为大小为uint_32
的单个IP地址,而不是使用uint_32
数组。有关详细信息,请参阅this post。sscanf
输出进行验证。%hu
扫描代码用于阅读unsigned short
和。{1}}
%hhu
扫描代码用于阅读unsigned char
。string
到unitt_32
以及使用inet_ntop从unitt_32
到string
的IP地址转换过程。如果您想了解更多信息,请阅读Beej网络书籍的this section。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]){
unsigned char ip_octects[4] = {0, 0, 0, 0};
uint32_t ip = 0;
unsigned short r1 = 0, r2 = 0;
unsigned char *str_c = "127,0,0,1,142,214";
if(sscanf(str_c, "%hhu,%hhu,%hhu,%hhu,%hu,%hu", &ip_octects[0],
&ip_octects[1], &ip_octects[2], &ip_octects[3], &r1, &r2) == 6){
printf("Extracted ip : port: %hhu.%hhu.%hhu.%hhu:%hu:%hu\n",
ip_octects[0], ip_octects[1], ip_octects[2], ip_octects[3], r1, r2);
ip = ip_octects[0] | ip_octects[1] << 8 |
ip_octects[2] << 16 | ip_octects[3] << 24;
printf("unit32_t ip value: %zu\n", ip);
/* We're done but lets verify the results using inet_pton() and inet_ntop() */
unsigned char *str_d = "127.0.0.1";
char str[INET_ADDRSTRLEN];
struct sockaddr_in sa;
if(inet_pton(AF_INET, str_d, &(sa.sin_addr)) < 1){
perror("error: invalid input for inet_pton"); exit(1);
}
printf("inet_pton ip value: %zu\n",sa.sin_addr);
if(inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN) == NULL){
perror("error: invalid input for inet_ntop"); exit(1);
}
printf("inet_ntop str value: %s\n", str);
}
else{
perror("error: invalid input for sscanf"); exit(1);
}
return (0);
}
答案 2 :(得分:-1)
Followling是我的代码,它似乎可以工作并打印出正确的结果。
char sentence []="127,0,0,1,123,64";
uint16_t ret_ip;
uint16_t ip1, ip2, ip3;
uint16_t temp1, temp2;
sscanf(sentence, "%d,%d,%d,%d,%d,%d", &ret_ip, &ip1, &ip2, &ip3, &temp1, &temp2);
printf("%d, %d\n", temp1, temp2);