【问题标题】:How to compare strings containing numbers just by letters in C如何仅通过C中的字母比较包含数字的字符串
【发布时间】:2017-05-16 11:18:06
【问题描述】:

我需要比较字符串,仅通过字母和 C 中数字的外观来比较字母和数字。

例如,字符串"first%dsecond%dj" 应被视为等于任何字符串,例如"first[number]second[number]j"

我试着这样做:

char *c_i
int i, j;
if (sscanf(c_i, "first%dsecond%dj", &i, &j) == 2 &&
    c_i[strlen(in) - 2] == 'j') {
    printf("%s", c_i);
}

但 sscanf 会忽略最后一个数字后面的所有内容,因此像 "first%dsecond%dthird%dj" 这样的字符串也会给出真实值并被打印出来。

通常sscanf 只关心最后一个说明符之前的字母值,我想找到一些也计算后面的字母的东西,比如一个比较器,它检查整个字符串并获取除数字之外的任何数字。

当然,我可以通过创建自己的char* 扫描器来做到这一点,但如果有更简单的方法,我想避免这种情况。

【问题讨论】:

    标签: c string string-comparison scanf


    【解决方案1】:

    使用%n 获取转换的长度,然后检查字符串是否真的到此结束:

    void checkString(const char *s)
    {
      int i, j, n = 0;
    
      if (sscanf(s, "first%dsecond%dj%n", &i, &j, &n) == 2 && s[n] == '\0') 
      {
        printf("%s", s);
      }
    }
    

    【讨论】:

      【解决方案2】:

      @unwind 的好答案的变化。

      使用"%n" 记录扫描中的当前位置,使用"*" 取消保存到int 的需要。

      n ... 对应的参数应该是一个指向有符号整数的指针,将通过调用fscanf 函数从输入流中读取的字符数写入该整数。 ... C11 §7.21.6.2 12

      一个可选的赋值抑制字符*。 §7.21.6.2 3

      // return true on match
      bool IE_compare(const char *c_i) {
        int n = 0;
        sscanf(c_i, "first%*dsecond%*dj%n", &n);
        return n > 0 && c_i[n] == '\0';
      }
      

      注意:格式字符串可以编码为单独的字符串文字以供替代阅读。

        sscanf(c_i, "first" "%*d" "second" "%*d" "j" "%n", &n);
      

      上面将匹配 "first +123second -456j" 这样的数字之前的前导空格,因为 "%d" 允许这样做。为了避免:

        int n1, n2,
        int n = 0;
        sscanf(c_i, "first%n%*dsecond%n%*dj%n", &n1, &n2, &n);
        return n > 0 && !isspace((unsigned char) c_i[n1]) && 
            !isspace((unsigned char) c_i[n2]) && c_i[n] == '\0';
      

      上面将匹配带有前导符号的数字,例如"first+123second-456j",因为"%d"允许这样做。为了避免:

        sscanf(c_i, "first%n%*dsecond%n%*dj%n", &n1, &n2, &n);
        return n > 0 && isdigit((unsigned char) c_i[n1]) && 
            isdigit((unsigned char) c_i[n2]) && c_i[n] == '\0';
      
        // or 
        int n = 0;
        sscanf(c_i, "first%*[0-9]second%*[0-9]j%n", &n);
        return n > 0 && c_i[n] == '\0';
      

      尚不清楚的是,数字的出现是否是必需的。 “......和一个数字的出现”意味着是的。 "firstsecondj" 应该匹配吗?以上答案假设没有。

      【讨论】:

      • 这真是一个很棒的答案!你是对的,有数字,“firstsecondj”和“first 2 second 4 j”都是错误的。谢谢! :)
      • @IpEsez 提示:与许多编码问题一样,良好的代码和效率源于精确的编码目标。 “数字”太松了。前导空格好吗?不 - 解决了。 标志 好吗?什么范围是有效的?必须是整数?没有号码好吗?对于这样一个小的编码任务,一个人可以编码多个候选者。在较大的程序中,这是不切实际的。有时简单地列出一些有效和无效的例子会有很大帮助。
      • 我会记得,我是编程新手,尤其是在 stackoverflow 上发布任何内容。再次感谢您的建议!
      猜你喜欢
      • 1970-01-01
      • 2017-07-03
      • 2016-02-18
      • 2021-03-03
      • 1970-01-01
      • 2010-12-12
      • 2023-03-19
      • 2016-05-05
      • 1970-01-01
      相关资源
      最近更新 更多