gpt4 book ai didi

c - 如何在 sscanf 中使用 set scanset 读取数字,如 0-9

转载 作者:太空宇宙 更新时间:2023-11-04 07:53:36 25 4
gpt4 key购买 nike

如何在 C 中的 sscanf 函数中使用 [0-9] 或 [a-z] 等扫描集读取输入。我们未能成功实现扫描集以成功扫描字符串。

这是我的例子:

void printResult(char * test, char * actual, char * expected)
{
printf("\n\n%d. %s\r",testcount++, test);

if(strcmp(actual,expected) == 0)
{
printf("SUCCESS\r");
printf("Output:%s", actual);
}
else
{
printf("FAILED\r");
printf("Expected Output:%s Actual Output:%s", expected, actual);
}
}
int main()
{
char buffer[] = "250MEL\r";
char * pBuffer = buffer;
char output[5]={0};
//1
sscanf(pBuffer,"%[ 0-9 ]s",output);
printResult("%[0-9]s", output, "250");

//2
sscanf(pBuffer,"%3[ 0-9 ]s",output);
printResult("%3[0-9]s", output, "250");


return 0;
}

谁能帮我正确使用扫描集。

最佳答案

TL;DR 目前尚不清楚是什么让您认为扫描集失败;他们在这种情况下对我来说工作正常。下面显示的经过轻微修改的代码证明了这一点。

正如我在 comment 中指出的那样,扫描集的形式为 %[…] — 它在 ] 和后面的任何内容(问题代码中的 s 处停止) 不是扫描集的一部分。如果您需要在扫描集中包含 ],它必须是第一个字符(如果您使用的是否定扫描集,则在否定扫描集的插入符号之后)。扫描集后有s,如果输入在数字和空白序列结束后包含s(扫描集中的第一个空白是有意义的;第二个, 作为重复, 不是), 然后该字符将被“消耗”并且下一个输入操作将在 s 之后继续;如果下一个字符不是 s,则将其留在输入中以供下一个输入操作使用。此外,如果下一个字符不是s,则匹配失败,但是sscanf() 无法报告当扫描集是最后一个或唯一一个时格式字符串中的转换规范。尾随上下文总是消耗性的;无法检测到它的缺失。

您的代码很奇怪,因为它在许多地方使用了 \r。您很少需要在 C 代码中使用 \r — 您应该在代码中使用 \n(或空白,或……)。

这是一个与您的程序非常相似的程序,但有一些更改。代码检查 sscanf() 的返回值;它用一些其他字符替换了大部分回车;它保留错误的格式字符串;它使 print 函数的参数与 sscanf() 函数的参数匹配。

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

static int testcount = 1;

static void printResult(char *test, char *actual, char *expected)
{
printf("\n\n%d. [%s]: ", testcount++, test);

if (strcmp(actual, expected) == 0)
{
printf("SUCCESS ");
printf("Output: [%s]\n", actual);
}
else
{
printf("FAILED ");
printf("Expected Output: [%s], Actual Output: [%s]\n", expected, actual);
}
}

int main(void)
{
char buffer[] = "250MEL\r";
char *pBuffer = buffer;
char output[5] = {0};
// 1
if (sscanf(pBuffer, "%[ 0-9 ]s", output) != 1)
printf("scanf() 1 failed\n");
printResult("%[ 0-9 ]s", output, "250");

// 2
if (sscanf(pBuffer, "%3[ 0-9 ]s", output) != 1)
printf("scanf() 1 failed\n");
printResult("%3[ 0-9 ]s", output, "250");

return 0;
}

它还会产生预期的输出:

1. [%[ 0-9 ]s]: SUCCESS  Output: [250]


2. [%3[ 0-9 ]s]: SUCCESS Output: [250]

如果您之前没有看到 SUCCESS,那是因为 \r 字符将写入位置移动到行的开头,所以后面的内容覆盖了 成功

辅助问题

Also, please let me know how can I set a range for A-Z like below — but this is not working:

sscanf(pBuffer,"%*[A-Z]s",output);
printResult("%[A-Z]s",output, "MEL" );

注意!

您的评论表明您仍然认为 %[…]s 是扫描集的符号,但 s 是虚假的;它不是扫描集符号的一部分。不要再将 %[…] 视为 %s 的修饰符;它不是修饰符。它是一个完全独立的转换规范,与 %s 几乎完全无关并且在语法上完全不同。方括号表示法也明确且明确地不是任何标准 printf() 转换规范语法的一部分。

这是一些基于答案的前一部分(因此基于问题中的代码)松散修改的代码。它不是恒星,但它确实显示了一些有用的信息。

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

static int strings_match(const char *actual, const char *expected);
static void printResult(const char *format, const char *data, const char *act1,
char *exp1, const char *act2, char *exp2);

int main(void)
{
char buffer1[] = "250MEL@93";
char buffer2[] = " 250 \t\tMELabc";
char number[5] = "";
char letters[5] = "";
const char fmt1[] = "%4[0-9]%4[A-Z]";
const char fmt2[] = " %4[0-9] %4[A-Z]";

if (sscanf(buffer1, fmt1, number, letters) != 2)
printf("sscanf() 1 failed\n");
else
printResult(fmt1, buffer1, number, "250", letters, "MEL");

if (sscanf(buffer2, fmt2, number, letters) != 2)
printf("sscanf() 2 failed\n");
else
printResult(fmt2, buffer2, number, "250", letters, "MEL");

number[0] = '\0';
letters[0] = '\0';
if (sscanf(buffer2, fmt1, number, letters) != 2)
printf("sscanf() 3 failed\n");
else
printResult(fmt2, buffer1, number, "250", letters, "MEL");

const char fmt3[] = "%4[0-9]s%c";
const char fmt4[] = "%4[0-9]%c";
char buffer3[] = "9876sun";
char buffer4[] = "9876moon";
char letter;

if (sscanf(buffer3, fmt3, number, &letter) != 2)
printf("sscanf() 4 failed\n");
else
printf("Data [%s], Format [%s], Output [%s] %c\n", buffer3, fmt3, number, letter);

if (sscanf(buffer3, fmt4, number, &letter) != 2)
printf("sscanf() 5 failed\n");
else
printf("Data [%s], Format [%s], Output [%s] %c\n", buffer3, fmt4, number, letter);

if (sscanf(buffer4, fmt3, number, &letter) != 2)
printf("sscanf() 6 failed\n");
else
printf("Data [%s], Format [%s], Output [%s] %c\n", buffer4, fmt3, number, letter);

return 0;
}

static int strings_match(const char *actual, const char *expected)
{
int rc;
if (strcmp(actual, expected) == 0)
{
rc = 1;
printf(" Output: [%s]", actual);
}
else
{
rc = 0;
printf(" Expected Output: [%s], Actual Output: [%s]", expected, actual);
}
return rc;
}

static int testcount = 1;

static void printResult(const char *format, const char *data, const char *act1,
char *exp1, const char *act2, char *exp2)
{
printf("Format: %d. [%s] Data: [%s]", testcount++, format, data);
int t1 = strings_match(act1, exp1);
int t2 = strings_match(act2, exp2);

if (t1 == 1 && t2 == 1)
printf(" - SUCCESS\n");
else
printf(" - FAILED\n");
}

输出:

Format: 1. [%4[0-9]%4[A-Z]] Data: [250MEL@93] Output: [250] Output: [MEL] - SUCCESS
Format: 2. [ %4[0-9] %4[A-Z]] Data: [ 250 MELabc] Output: [250] Output: [MEL] - SUCCESS
sscanf() 3 failed
Data [9876sun], Format [%4[0-9]s%c], Output [9876] u
Data [9876sun], Format [%4[0-9]%c], Output [9876] s
sscanf() 6 failed

注意最后两行成功的转换行有何不同——格式字符串中的 s 作为文字与数据匹配,留下 u 被读入字符, 与格式字符串中没有 s 并且字符匹配 s 时相比。相反,当格式查找 s 并找到 m 时,整个 sscanf() 失败 — 它只管理 1 个而不是 2 个转换规范。

关于c - 如何在 sscanf 中使用 set scanset 读取数字,如 0-9,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52117158/

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