使用sscanf从字符串中提取(可能是空的)单词(用“分隔”)

使用sscanf从字符串中提取(可能是空的)单词(用“分隔”),c,C,我想从字符串中提取单词 我不想使用strtok,因为它会破坏我的源字符串。另一件事是,我想知道是否有可能管理做我想不使用周期 这是我的代码示例。它成功地读取了第一个单词,但第二个和第三个单词仍然为空 char source[] = "XXX|YYY|ZZZ"; char word1[10] = ""; char word2[10] = ""; char word3[10] = ""; sscanf( source, "%[^|]s|%[^|]s|%s", word1, word2, word

我想从字符串中提取单词

我不想使用strtok,因为它会破坏我的源字符串。另一件事是,我想知道是否有可能管理做我想不使用周期

这是我的代码示例。它成功地读取了第一个单词,但第二个和第三个单词仍然为空

char source[] = "XXX|YYY|ZZZ";

char word1[10] = "";
char word2[10] = "";
char word3[10] = "";

sscanf( source, "%[^|]s|%[^|]s|%s", word1, word2, word3 );
使用
sscanf
真的有可能吗?还是我走错了路

更新:

看起来user3121023的答案对空单词不起作用

char source[] = "XXX||ZZZ";

char word1[10] = "";
char word2[10] = "";
char word3[10] = "";

sscanf( source, "%[^|]|%[^|]|%s", word1, word2, word3 );
第三个字仍然是空的。在这种情况下我该怎么办?

您的
sscanf()
格式不会清空子字符串,如果目标数组小于源字符串,它也不会防止潜在的缓冲区溢出

下面是一个带有
strcspn()
和实用函数
strcpy\n
的解决方案:

#include <string.h>

char *strcpy_n(char *dest, size_t size, const char *src, size_t n) {
    if (size > 0) {
        if (n >= size)
            n = size - 1;
        memcpy(dest, src, n);
        dest[n] = '\0';
    }
    return dest;
}

...

    char source[] = "XXX||ZZZ";
    char word1[10], word2[10], word3[10] = "";

    size_t pos = 0, len;

    len = strcspn(source + pos, "|");
    strcpy_n(word1, sizeof(word1), source + pos, len);
    pos = pos + len + (source[pos + len] == '|');

    len = strcspn(source + pos, "|");
    strcpy_n(word2, sizeof(word2), source + pos, len);
    pos = pos + len + (source[pos + len] == '|');

    len = strcspn(source + pos, "|");
    strcpy_n(word3, sizeof(word3), source + pos, len);
    pos = pos + len + (source[pos + len] == '|');

...

@用户3121023:谢谢!它起作用了@Jean-François Fabre:你说得对——但我花了一个小时试图在互联网上找到我的问题的答案,结果却没有显示出来。注意:这是以“”的副本关闭的,但这里有“空词”的限制。所以我重新开门了,谢谢。这是一个非常精确的解决方案。
/* returns non zero if there are more fields to parse */
int getfield(char *dest, size_t size, const char *source, size_t *ppos) {
    int has_separator = 0;
    size_t pos = *ppos;
    size_t len = strcspn(source + pos, "|");
    strcpy_n(dest, size, source + pos, len);
    pos += len;
    has_separator = (source[pos] == '|');
    *ppos = pos + has_separator;
    return has_separator;
}

 ...

    char source[] = "XXX||ZZZ";
    char word1[10], word2[10], word3[10];

    size_t pos = 0;

    /* parse the fields, empty and missing fields are set to "" */
    getfield(word1, sizeof(word1), source, &pos);
    getfield(word2, sizeof(word2), source, &pos);
    getfield(word3, sizeof(word3), source, &pos);

...