使用scanf解析字符串时出现奇怪的行为

时间:2014-05-14 22:46:15

标签: c scanf

我在预制sscanf时遇到了相当奇怪的行为。目前正在使用c。

中的Windows 7机器

我有以下内容:

if( sscanf( str, "%1[a-zA-Z]%31[a-zA-Z+.-]%n", &scheme[ 0 ], &scheme[ 1 ], &num_chars ) >= 1 )
  {
  return( num_chars );
  }

str变量是一个大的输入字符串,可能大于32个字符。 scheme变量被声明为包装函数调用的参数,它是一个32个字符的数组。

我可以使用几个scanfs或两个单独的变量轻松完成此操作。我只是好奇为什么它不能按原样运作。

修改
当我执行此操作并且错误发生时包含" tel-net" (正在测试' - ')并导致方案字符串基本上没有可用的字符。

解决方案:
我弄清楚问题是什么,它实际上根本不是一个scanf问题。

这是我宣布方案变量的方式:

IOP_uri_scheme_type   * scheme_str;

IOP_uri_scheme_type声明如下:

typedef char    IOP_uri_scheme_type[ IOP_URI_MAX_SCHEME_SZ ];  // Size = 32

问题是索引,方案[1]实际上是跳过整个块(所有32个字节),而不是像我期待的那样的字符。所以从技术上讲,scanf是正确编写的(减去%n)。

我可以解决这个问题的一种可能方法是首先将方案转换为(char *)或直接操作指针值,取消引用它,或者只是不使用我不需要的指针。 / p>

感谢大家的帮助。

2 个答案:

答案 0 :(得分:3)

您似乎正在尝试在sscanf中使用正则表达式。据我所知,sscanf对正则表达式没有任何支持。

答案 1 :(得分:0)

这是我为此案例制作的测试套件(尺寸因可读性而降低):

#include <stdio.h>

int main()
{
    char str[] = "tel-net";
    char scheme[13] = { 0 };
    int num_chars;
    int result = sscanf( str, "%1[a-zA-Z]%11[a-zA-Z+.-]%n",
                            &scheme[ 0 ], &scheme[ 1 ], &num_chars );

    printf("result = %d\n", result);
    printf("scheme = '%s'\n", scheme);

    printf("scheme = ");
    for (int ii = 0; ii < sizeof scheme; ++ii)
        printf("%02x ", (unsigned char)scheme[ii]);
    printf("\n");

    if ( result == 2 )
        printf("num_chars = %d\n", num_chars);

    return 0;
}

输出为:

result = 2
scheme = 'tel-net'
scheme = 74 65 6c 2d 6e 65 74 00 00 00 00 00 00
num_chars = 7

你可以发布你的输出吗?

请注意,您的程序存在错误,因为如果第二个%n失败,则不会处理[。如果返回值正好为num_chars,则只能返回2

关于“正则表达式”:根据C标准,它是实现定义的当你在[ ]说明符中使用连字符时会发生什么。您的编译器(加上C库等)可能支持也可能不支持您正在尝试的用法。查看编译器的scanf文档,了解它对此案例的说法。

NB。我最初发布了一个答案,说它是未定义的,以读取重叠的对象 - 但我认为这实际上是错误的,它很好,因为参数按顺序处理(标准并没有说它是未定义的)。