【问题标题】:Reading a specific string using Scanf()使用 Scanf() 读取特定字符串
【发布时间】:2016-04-27 04:28:54
【问题描述】:

我正在尝试使用 scanf() 在 C 中读取具有特定格式的字符串 该字符串的格式为:

<LET,LET,LET> op

其中LET 是大写字母,op 必须是'+''%'

这些是有效的条目:

<A,B,C> +
<A,W,Z> %
<Q,   X,W>    +

这些不是:

<A,b,C> +
<A,W,Zddddd> %
<Q,X,W> *

我正在尝试这样的事情

#include <stdio.h>

int ret = 0;
char str[8];
ret = scanf("%8[^\n]",str);

str 以垃圾告终。我只是不知道如何阅读它以及如何只获取大写字母。

谢谢

【问题讨论】:

  • 你希望读入 str 什么?
  • 对不起。字符串的格式为: op 其中 LET 是大写字母,op 必须是 '+' 或 '%'。
  • 你的例子有 + 和 * 作为 op,三个都是括号中的数字。
  • 我修好了。 LET 是大写字母,op 必须是 + 或 %
  • 应该"&lt;A,W,Zddddd&gt; % qwerty" work 还是失败?

标签: c text io formatting scanf


【解决方案1】:

试试这个:

#include <stdio.h>

int main(void) {
    char let1[2], let2[2], let3[2], op[2];
    char line[80];
    while(fgets(line, sizeof line, stdin)){
        if(sscanf(line, "<%1[A-Z], %1[A-Z], %1[A-Z]> %1[+%]", let1, let2, let3, op) == 4)
            puts("valid");
        else
            puts("invalid");
    }

    return 0;
} 

【讨论】:

  • 为什么 line 是 [80],为什么每个 let 是 [2]?
  • [80] 是我的控制台的宽度大小。请更改为您需要的大小。(但是,在 8 中它很小)[2]:一个字符 + 空终止符。
  • 这很好用。但是,如果我在逗号之前添加一个空格,它就不起作用。我应该在每个 %1[A-Z], 的逗号后添加一个空格吗?
  • 如果编译器不允许A-Z,则将其替换为ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • @Telefang 尝试在逗号前后添加一个空格。 (例如%1[A-Z] , %1[A-Z])这似乎对我有用。
【解决方案2】:

此方法还可以检测线路上的线索垃圾。

"%n" 保存当前扫描的偏移量。只有当n 不为零并且索引'\0' 时才会成功。

通过使用字符串文字连接,代码可以清楚地显示扫描的各个部分所使用的格式。

#include <stdio.h>

#define F_LET " %1[A-Z]"
#define F_SEP " ,"
#define F_OP  " %1[+%]"

int main(void) {
  char buf[100];
  while (fgets(buf, sizeof buf, stdin)) {
    char let[3][2];
    char op[2];
    int n = 0;
    sscanf(buf, " <" F_LET F_SEP F_LET F_SEP F_LET " >" F_OP " %n", 
        let[0], let[1], let[2], op, &n);

    puts((n && buf[n] == '\0') ? "Success" : "Fail");
  }
}

【讨论】:

    【解决方案3】:

    BLUEPIXY 的完美答案的替代方法是简单地使用 char,然后使用 %c 扫描输入,例如:

    #include <stdio.h>
    #include <ctype.h>
    
    int main()
    {
        char let1, let2, let3, op;
        char line[80]; // or some other suitable size
    
        while (fgets(line, sizeof line, stdin))
        {
            if (sscanf(line, "< %c , %c , %c > %c", &let1, &let2, &let3, &op) == 4 && (op == '+' || op == '%') && isupper(let1) && isupper(let2) && isupper(let3))
            {
                printf("valid!\nlet1 = %c\nlet2 = %c\nlet3 = %c\nop = %c\n", let1, let2, let3, op);
            }
            else
            {
                puts("invalid");
            }
        }
    }
    

    请注意%c 前后的空格很重要,因为它们允许sscanf 在尝试匹配%c 或逗号之前吞噬所有空格。

    然而,与 BLUEPIXY 的答案不同,我们必须手动检查 op 是否与 +% 匹配。

    编辑:我错过了 LET 字符必须为大写的部分。我已经确定了答案,但当然,现在更复杂了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多