0

我有一个 SPARQL 查询,例如“select ?Y ?Z where ...”。我要做的就是提取变量“?Y”和“?Z”。我写了以下循环:

char *p = "select ?Y ?Z where condition";
char *array[2];

p += strlen("select");        /* advancing the pointer */

for(int i = 0; i < 2; i++)
{
        sscanf(p, "%m[?a-zA-Z] %[^\n]", array[i], p);    /* 'm' tells sscanf to perform dynamic memory allocation */
        printf("%s, ", array[i]);
        printf("%s, ", p);
}

但是,我没有得到预期的行为。array[1] 包含垃圾,array[2] 包含 null。

4

2 回答 2

2

基于http://man7.org/linux/man-pages/man3/scanf.3.html
在示例中有

char *p;
n = scanf("%m[a-z]", &p);

我认为你应该改变你的

sscanf(p, "%m[?a-zA-Z] %[^\n]", array[i], p);

sscanf(p, "%m[?a-zA-Z] %[^\n]", &array[i], p);

看看如何%mchar **not with配对char*

我建议也阅读这个讨论。

我还注意到您的pischar *并且您使用字符串常量对其进行了初始化,然后尝试通过调用 sscanf 来覆盖它。

p除此之外,您在同一个函数调用中读取和写入内存点。我在这里不是 100% 确定,但这可能是未定义的行为。

希望能帮助到你。

于 2013-11-10T23:23:27.923 回答
1

你有几个问题。zubergu在他的回答中正确诊断了两个:(1) 在需要 a 的char *地方传递 a char **(请参阅scanf()),以及 (2) 尝试覆盖您正在扫描的字符串,该字符串首先是只读的,并且在任何情况下都会调用未定义的行为。

另一个是您没有检查退货状态sscanf()。你可能需要这样的东西:

char *p = "select ?Y ?Z where condition";
char *array[2];

p += strlen("select");

for (int i = 0; i < 2; i++)
{
    int offset;
    if (sscanf(p, " %m[?a-zA-Z]%n", &array[i], &offset) != 1)
        ...report error and break loop...
    printf("%s, ", array[i]);
    p += offset;
}

请注意转换规范之前的空白以跳过前导空格。

如果您有sscanf()支持该符号的版本,则此代码应该可以正常工作:

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

int main(void)
{
    char *p = "select ?Y ?Z where condition";
    char *array[2] = { 0, 0 };
    int i;
    int j;

    p += strlen("select");

    for (i = 0; i < 2; i++)
    {
        int offset;
        printf("p = <<%s>>\n", p);
        if (sscanf(p, " %m[?a-zA-Z]%n", &array[i], &offset) != 1)
            break;
        printf("%d: <<%s>> (offset = %d)\n", i, array[i], offset);
        p += offset;
    }
    printf("%d: all done\n", i);

    for (j = 0; j < i; j++)
        free(array[j]);
    return 0;
}

Mac OS X 10.9 不支持m修饰符;旧版本的 Linux 也没有(自我注意:必须更新可用的虚拟机)。在 Ubuntu 12.04 衍生版本上进行测试时,我得到了输出:

p = << ?Y ?Z where condition>>
0: <<?Y>> (offset = 3)
p = << ?Z where condition>>
1: <<?Z>> (offset = 3)
2: all done
于 2013-11-11T00:23:51.277 回答