首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用sscanf中的set扫描集读取0-9这样的数字

如何使用sscanf中的set扫描集读取0-9这样的数字
EN

Stack Overflow用户
提问于 2018-08-31 14:02:23
回答 1查看 1.3K关注 0票数 0

在C.We中,如何用扫描集(0-9)或扫描函数(A)读取输入,无法成功地实现扫描集,从而成功地扫描字符串。

这就是我的例子:

代码语言:javascript
运行
复制
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;
    }

你能帮我正确地使用扫描集吗?

EN

回答 1

Stack Overflow用户

发布于 2018-08-31 21:35:10

TL;博士还不清楚是什么让你认为你的扫描装置失败了;在这种情况下,它们对我来说是正常的。下面所示的稍加修改的代码演示了这一点。

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

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

这是一个基于你的程序,有一些变化。代码检查来自sscanf()的返回值;它用其他字符替换大部分回车;它保留错误的格式字符串;它使打印函数的参数与sscanf()函数的参数匹配。

代码语言:javascript
运行
复制
#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;
}

它还产生了预期的产出:

代码语言:javascript
运行
复制
1. [%[ 0-9 ]s]: SUCCESS  Output: [250]


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

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

辅助性问题

另外,请让我知道如何为A设定一个范围,如下所示-但这是行不通的: (pBuffer,“%*A”,输出);printResult(“%A”,输出,"MEL“);

请注意!

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

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

代码语言:javascript
运行
复制
#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");
}

输出:

代码语言:javascript
运行
复制
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个转换规范。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52117158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档