- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
如何在 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/
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
我在程序中遇到了以下行。通过阅读手册,我知道 sscanf 从 argv[2] 指向的任何地方复制,但我不确定为什么格式被指定为 %d,同时指定为 %c (我见过其他双引号中包含更多格式说明符的示例)
我可以使用字符指针 (char *) 作为 sscanf() 函数中的输出字符串吗?考虑到我不知道字符串的长度(这就是我使用指针的原因)。 char *name; sscanf(data, "Name
我有一个表单的输入字符串 char *s = "one.two three" 我想把它分成 3 个字符串变量。我在做 sscanf(s, "%s.%s %s", one, two, three); 但
我一直在尝试让 sscanf 使用字符类识别一种相当简单的格式。我注意到,当我为 sscanf 提供 char* 以匹配字符类时,它也会覆盖前一个字节,就好像它需要一个指向 2 个字节的指针一样。 我
我正在将 MAC 地址的字符串表示形式转换为 UINT8 的数组s 定义为 unsigned char 。我很好奇为什么sscanf()当我读入 UINT8 数组时,将读取全 0当我读入常规 32 位
我有一个包含空格和标签的字符串,例如: sp|P02671|FIBA_HUMAN Fibrinogen alpha chain OS=Homo sapiens GN=FGA PE=1 SV=2 我只想
我正在尝试在 C 中使用 sscanf 函数,但它不读取格式是必需的,我已经阅读了该函数的文档并遵循了示例,但它对我来说仍然效果不佳,因此我想要一些建议.. int main() { long i
我需要在c中解析一个格式为“foo=%d”的字符串,我需要检查格式是否正确并读取int值。 我的初始代码是: int foo_set = 0; int foo; if (sscanf(text, "f
在下面的代码中,我想读取十六进制字符串 'a' 中的前 2 个字符,使用 sscanf 将它们转换为相应的字节值并将结果放入 'b'。不应对“a”执行任何修改。 #include #include
我试图找出我应该给 sscanf 的模式。 我有一个字符串 abcde(1GB)。我想提取 1 和 GB。我在用 char list[]= "abcde(1GB)"; int memo
我应该得到一个可以是以下任何格式的输入行: 单词 1 和单词 2 之间必须有空格。 单词 2 和单词 3 之间必须有逗号。 单词 2 和单词 3 之间不一定要有空格,但可以有任意数量的空格。 如何分离
最近发现的对 GTA 冗长加载时间 (1) 的解释表明 sscanf() 的许多实现调用 strlen()在他们的输入字符串上为与其他扫描函数( scanf() , fscanf() ...)共享的内
我需要将字符串分成两部分,字符串的第一列是第一部分,字符串的其余部分是第二部分。第一部分需要存储在 first_str 中,第二部分需要存储在 rest_str 中。 我正在使用 sscanf 来实现
我需要从char数组中提取数字,它以hh:mm的格式存储值(示例20:20) 我尝试使用sscanf函数将hh提取为小时变量,将mm提取为分钟变量。 直到时间类似于0number:0number或如果
所以我想知道 sscanf 在遇到像这样的行时是如何工作的: sscanf(input_string, "%s %s %s", cmd1, cmd2, cmd3); 但是假设 input_string
我在以下代码中遇到 sscanf() 问题: void num_check(const char*ps){ char *ps1=NULL; int number=0; unsigned sum_num
谁能解释一下为什么在下面的代码中没有拆分字符串 #include int main(void) { char name[] = "first:last"; char first[20
我正在尝试解析一个 URL,并编写了这段代码: #include int main() { char host[100]; char port[100]; char path
我正在为我正在制作的程序使用 AT 命令,但在使用 sscanf() 函数解析它们时遇到问题。 例如,如果我执行此命令: "AT\r\r\nOK\r\n" 我想:* 在第一次调用时,仅获取“AT”部分
我是一名优秀的程序员,十分优秀!