问题来自sscanf

时间:2012-07-20 14:02:28

标签: c char handle

所有这些可能都是一个非常简单的但我错过了一些东西,希望你能提供帮助。好的,这是我的问题,就像我可以说的那样简单。

使用USB设备后,我将从readfile返回缓冲区。这一切都运行正常,我可以通过使用像这样的循环来缓冲缓冲区

for (long i=0; i<sizeof(buffer); i++)  //for all chars in string
{
    unsigned char c = buffer[i];

    switch (Format)
    {
        case 2:         //hex
            printf("%02x",c);
        break;
        case 1:         //asc
            printf("%c",c);
        break;
    }  //end of switch format
}

当我使用文本(%c)版本时,我可以按照我预期的方式在屏幕上看到缓冲区中的数据。但是我的问题是当我使用sscanf来阅读它时。我使用strstr搜索缓冲区中的某些键,并使用sscanf检索其数据。但是,sscanf失败。可能是什么问题?

下面是我用来扫描缓冲区的代码示例,它可以在这个独立版本中正常运行。上面代码中的缓冲区部分无法读取。即使我可以使用printf看到它。

#include <stdio.h> 
#include <string.h> 
#include <windows.h> 

int main () 
{ 
    // in my application this comes from the handle and readfile
    char buffer[255]="CODE-12345.MEP-12453.PRD-222.CODE-12355" ;    
    //
    int i; 
    int codes[256];  
    char *pos = buffer;  
    size_t current = 0;  
    //  
    while ((pos=strstr(pos, "PRD")) != NULL) {  
        if (sscanf(pos, "PRD - %d", codes+current))  
            ++current;  
        pos += 4;  
    }  

    for (i=0; i<current; i++) 
        printf("%d\n", codes[i]); 
    system("pause");
    return 0; 
} 

由于

1 个答案:

答案 0 :(得分:2)

问题是,您的ReadFile在您感兴趣的数据之前为您提供了不可打印的字符,特别是在开头的'\0'。由于C中的字符串是NUL终止的,因此所有标准函数都假定缓冲区中没有任何内容。

我不知道您正在阅读的是什么,但也许您正在阅读包含标题的消息?在这种情况下,您应该首先跳过标题。

盲目地尝试解决问题,你可以手动跳过坏字符,假设它们都在开头。

首先,让我们确保缓冲区始终以NUL终止:

char buffer[1000 + 1];    // +1 in case it read all 1000 characters
ReadFile(h,buffer,0x224,&read,NULL);
buffer[read] = '\0';

然后,我们知道read填充了ReadFile个字节数。我们首先需要从中回过头来找出好数据的起源。然后,我们需要更进一步,找到数据不感兴趣的第一个地方。请注意,我假设在消息的末尾,没有可打印的字符。如果有,那就变得更复杂了。在这种情况下,最好是编写自己的strstr,但不会在'\0'上终止,但会读取给定的长度。

所以而不是

char *pos = buffer;

我们

// strip away the bad part in the end
for (; read > 0; --read)
    if (buffer[read - 1] >= ' ' && buffer[read - 1] <= 126)
        break;
buffer[read] = '\0';
// find where the good data start
int good_position;
for (good_position = read; good_position > 0; --good_position)
    if (buffer[good_position - 1] < ' ' || buffer[good_position - 1] > 126)
        break;
char *pos = buffer + good_position;

其余的可以保持不变。

注意:我是从数组的后面开始的,因为假设开头是标题,那么它可能包含可能被解释为可打印字符的数据。另一方面,最后它可能全是零或什么的。