gpt4 book ai didi

c - 以特殊格式将空字符串与scanf匹配的问题

转载 作者:太空宇宙 更新时间:2023-11-04 01:45:46 24 4
gpt4 key购买 nike

我有具有特殊条件的 CUSTOM_PROMPT_REGX 模式。

它应该捕获 10 个以 |# 作为分隔符的文本。它们每个都可以为空,因此 |# 之间没有字符,就像 "..|#..."

我的代码是:

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


#define CUSTOM_PROMPT_REGX "@%39[^|]|%39[^#]#%39[^|]|%39[^#]#%39[^|]|%39[^#]#%39[^|]|%39[^#]#%39[^|]|%39[^@]@"
static unsigned char lines[5][2][40];

int main(void)
{
memset(lines, 0, sizeof(lines));
int j = sscanf("@1.SALAM|818BF4F2A8#2.BINGO|828BF8F0F7FE93#3.GOOGLE|838BF1F0F8F0#|#5.WINE|858BF6FE90F8@", CUSTOM_PROMPT_REGX,
lines[0][0], lines[0][1], lines[1][0], lines[1][1],
lines[2][0], lines[2][1], lines[3][0], lines[3][1], lines[4][0], lines[4][1]);

printf("%d\n[%s <=> %s]\n[%s <=> %s]\n[%s <=> %s]\n[%s <=> %s]\n[%s <=> %s]\n", j,
lines[0][0], lines[0][1], lines[1][0], lines[1][1], lines[2][0], lines[2][1],
lines[3][0], lines[3][1], lines[4][0], lines[4][1]);
return 0;
}

结果是:

6
[1.SALAM <=> 818BF4F2A8]
[2.BINGO <=> 828BF8F0F7FE93]
[3.GOOGLE <=> 838BF1F0F8F0]
[ <=> ]
[ <=> ]
Press <RETURN> to close this window...

应该是:

8
[1.SALAM <=> 818BF4F2A8]
[2.BINGO <=> 828BF8F0F7FE93]
[3.GOOGLE <=> 838BF1F0F8F0]
[ <=> ]
[5.WINE <=> 858BF6FE90F8]

有什么我可以添加到 CUSTOM_PROMPT_REGX 来解决我的问题吗?

最佳答案

Each of them can be empty so there is no characters between ...
... is there some thing that i can add to CUSTOM_PROMPT_REGX to solve my problem?

没有。 %[...] 在没有任何内容扫描到说明符时停止整个 sscanf()。至少有 1 个字符必须符合扫描集

备选方案:

  1. 一次使用一个%[...] 指令进行扫描。更容易制作一个循环来执行此操作。

  2. 使用非 sscanf() 方法。研究 strtok()、strspn()、strcspn()

  3. 将前导分隔符扫描到字符串中,然后使用从索引 1 开始的字符串。在 OP 的情况下,3 个分隔符中没有 2 个连续使用,因此这是一种可能的方法。

  4. 每个 "%79[^#]# 扫描成 5 组,然后对每个进行 segmentation 。研究 strchr(buf80, '|');


提示

复杂的 sscanf() 格式通过使用字符串文字 连接更易于编码、审查和维护。

#define VB_FMT "%39[^|]|"
#define LB_FMT "%39[^#]#"
#define AT_FMT "%39[^@]@"
#define CUSTOM_PROMPT_REGX "@" \
VB_FMT LB_FMT VB_FMT LB_FMT VB_FMT LB_FMT VB_FMT LB_FMT VB_FMT AT_FMT

一次执行 1 个 sscanf() "%[]" 说明符的示例代码。

int main() {
#define ATVB_FMT "@%n%39[^|]%n"
#define VBLB_FMT "|%n%39[^#]%n"
#define LBVB_FMT "#%n%39[^|]%n"
#define VBAT_FMT "|%n%39[^@]@%n"
#define N 10

const char *fmt[10] = {ATVB_FMT, VBLB_FMT, LBVB_FMT, VBLB_FMT, LBVB_FMT,
VBLB_FMT, LBVB_FMT, VBLB_FMT, LBVB_FMT, VBAT_FMT};

char lines[N][40];

const char *buf = \
"@1.SALAM|818BF4F2A8#2.BINGO|828BF8F0F7FE93#3.GOOGLE|838BF1F0F8F0#|#5.WINE|858BF6FE90F8@";
const char *s = buf;

for (int i = 0; i<N; i++) {
int n1 = 0;
int n2 = 0;
sscanf(s, fmt[i], &n1, lines[i], &n2);
if (n1 == 0) {
fprintf(stderr, "Failed to find separator %d\n", i);
return EXIT_FAILURE;
}
if (n2 == 0) {
lines[i][0] = '\0';
s += n1;
} else {
s += n2;
}
}

if (*s) {
fprintf(stderr, "Failed end %d\n", N);
return EXIT_FAILURE;
}

for (int i = 0; i<N; i++) {
printf("<%s>\n", lines[i]);
}
return 0;
}

输出

<1.SALAM>
<818BF4F2A8>
<2.BINGO>
<828BF8F0F7FE93>
<3.GOOGLE>
<838BF1F0F8F0>
<>
<>
<5.WINE>
<858BF6FE90F8>

关于c - 以特殊格式将空字符串与scanf匹配的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54105766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com