为什么sscanf对这种情况不起作用?

时间:2014-10-23 16:28:29

标签: c windows scanf

目前我正在阅读文件,并打印(stdout)它包含的所有单词/字符串。

以下是代码:

int scan_strings(FILE *in, FILE *out) 
{
    char buffer[64];
    int i = 0, n = 0;

    for(;;)
    {
        if (fscanf(in, "%*[^" charset "]") != EOF)
        {
            i = 0;
            while (fscanf(in, "%63[" charset "]%n", buffer, &n) == 1)
            {
                if (n < 4 && i == 0)
                {
                    break;
                }
                else
                {
                    i = 1;
                }

                fputs(buffer, out);
            }
            if (i != 0)
            {
                putc('\n', out);
            }
        }
        if (feof(in))
        {
            return 0;
        }
        if (ferror(in) || ferror(out))
        {
            return -1;
        }
    }
}

但是我想要做的是从已经读取到内存的缓冲区中搜索字符串。

我将inout个变量更改为unsigned char*,并将fscanf更改为sscanf。然而,这不起作用。我误解了sscanf函数,还是我的代码中还有其他错误?

如何从已读缓冲区打印所有字符串?数据是二进制数据。

我正在开发Windows,并且不需要Linux可移植性。

2 个答案:

答案 0 :(得分:1)

sscanf(data, "%*[^" charset "]")fscanf(in, "%*[^" charset "]")的工作方式不同。当数据是二进制时。

假设charset是一些字符串,如&#34; 123&#34;。

只要fscanf(in, "%*[^123]")读取不是inchar'1'

'2'就会扫描'3'。 此包含 '\0'

只要sscanf(data, "%*[^123]")读取不是datachar'1'

'2'就会扫描'3'不包括 '\0'sscanf退出,一旦遇到char,就会提供'\0'进行扫描。

无法使用sscanf()扫描'\0'


[编辑]

OP:我应该怎样做 - 对于二进制数据(来自缓冲区/变量)? 答:sscanf() 周围的附加代码可用于应对遇到'\0'时停止扫描的问题。像第一个sscanf()的东西:

size_t j=0;
for (;;) {

  // if (fscanf(in, "%*[^" charset "]") != EOF)
  while (j < datasize) {
    int n = 0;
    sscanf(&data[j], "%*[^123]%n", &n);
    if (n > 0) j += n;
    else if (data[j] == '\0') j++;
    else break; 
  }

  if (j < datasize) {
    i = 0;
    ...

你可以看到事情越来越难看 让我们尝试将strchr()与未经测试的代码一起使用:

size_t j=0;
for (;;) {

  while (j < datasize) {
    int ch = data[j];
    if (ch && strchr(charset, ch) != NULL) break;
    j++;
  }

  if (j < datasize) {
    i = 0;
    ...

变得更好,这只适用于第一个sscanf()

答案 1 :(得分:0)

问题是您的代码永远不会修改in。如果in是文件fscanf,则会按顺序移动它。但是sscanf并没有这样做。

您需要找出有多少字符sscanf读取,然后相应地增加in

您已经获得n中读取的字节数,因此只需将其添加到in

 in += n;

...在sscanf之后。