-1

我在这段代码中使用 sscanf

while(totalByte < sizeof(rdata)) 
{   
    read(client_sockfd, &buffer[totalByte],1); 
    printf("bytes[%d] : %x \n", totalByte, buffer[++totalByte]);
}

使用这段代码,我得到了这样的结果

客户端发送 1 1 +

bytes[0] : 0  
bytes[1] : 0  
bytes[2] : 0  
bytes[3] : 1  
bytes[4] : 0  
bytes[5] : 0
bytes[6] : 0  
bytes[7] : 1  
bytes[8] : 2b 
bytes[9] : 0  
bytes[10] : 0  
bytes[11] : 0 
bytes[12] : 0  
bytes[13] : 0  
bytes[14] : 0  
bytes[15] : 0  
bytes[16] : 0  
bytes[17] : 0 
bytes[18] : 0  
bytes[19] : 0 

得到了结果

然后我使用 sscanf 方法

sscanf(buffer,"%d%d%c" ,&rdata.left_num, &rdata.right_num, rdata.op); 
printf("%d %c %d \n", ntohl(rdata.left_num),rdata.op,ntohl(rdata.right_num));

但是当打印 rdata(结构)的值时,得到一个 0 值(初始值)。

0 0

我知道 sscanf 方法拆分字符串并插入一个值

对我有什么误解吗?

这就是我使用的结构

struct cal_data 
{  
    int left_num;  
    int right_num;
    char op;  
    int result;  
    int error;  
}; 
4

3 回答 3

3

我不认为这是在做你想做的事:

printf("bytes[%d] : %x \n",totalByte, buffer[++totalByte]);

如果这有效,那么它的工作是巧合。你不想依赖巧合,而不是逻辑,是吗?阅读此问题以获取有关此处未定义行为的更多信息。将其更改为此,并避免省略序列点以便将来将逻辑拼凑在一起:

printf("bytes[%d] : %x \n",totalByte, (unsigned int) buffer[totalByte]);
totalByte++;

然后我使用 sscanf 方法 sscanf(buffer,"%d%d%c" ,&rdata.left_num, &rdata.right_num, rdata.op);

你的错误检查在哪里?像大多数标准 C 函数一样,您的代码应该检查 sscanf 的返回值,以确保它提取了您想要的信息量。您如何确定 sscanf 成功处理了两个十进制数字序列和一个字符?用这个:

int n = sscanf(buffer,"%d%d%c" ,&rdata.left_num, &rdata.right_num, rdata.op);
if (n == 3) {
    /* sscanf extracted and assigned three values;
     * One for each of the format specifiers,
     * and variables you passed in. Success! */
    printf("%d %c %d \n", ntohl(rdata.left_num),rdata.op,ntohl(rdata.right_num));
}
else {
    /* sscanf failed to extract some values from the string,
     * because the string wasn't correctly formatted */
    puts("Invalid input to sscanf");
}

...现在您会看到问题所在!sscanf 失败!

正如其他人所指出的,字符串在第一个'\0'(或 0)字节处终止。您传递给 sscanf 的指针指向一个空字符串。sscanf 无法从空字符串中提取您想要的任何信息。

于 2013-04-06T02:32:04.647 回答
2

sscanf像许多其他 C 库函数一样,当字符串到达​​ 0(与 '\0' 相同)时,它会停止迭代字符串。数组的第一个元素bytes是 0。因此,就 sscanf 而言,用于的输入字符串sscanf"". while要查看此行为的另一个示例,请在循环后添加以下代码。

printf("%s\n", bytes);

这不会打印任何东西(将打印一个空字符串),因为printflikesscanf会认为byte[0]是字符串的结尾。

您可能应该使用这样的东西将数据读入您的结构 - http://c-faq.com/stdio/extconform.html

于 2013-04-06T02:10:39.027 回答
1

根据功能描述(http://www.cplusplus.com/reference/cstdio/sscanf/):

int sscanf ( const char * s, const char * format, ...);

第一个论点应该是:

C string that the function processes as its source to retrieve the data.

但是当您将每个字节打印为“十六进制整数”时:

printf("bytes[%d] : %x \n", totalByte, buffer[++totalByte]);

第一个字节的值为0。所以如果你把它当作一个字符串,它就是一个空字符串。

于 2013-04-06T02:14:44.297 回答