识别字符串中间的10位数字

时间:2013-10-04 13:43:28

标签: c

我可以包含包含随机10位数字的字符串,例如 "abcgfg1234567890gfggf""fgfghgh3215556890ddf"

基本上是字符串中10个数字加字符的任意组合,所以我需要检查字符串以确定是否存在10位数字。我使用strspn但它返回0

char str_in[] = "abcgfg1234567890gfggf";
char cset[] = "1234567890";    
int result;

result = strspn(str_in, cset);   // returns 0   need it to return 10

以下代码返回0而不是10的事实凸显了该问题。我之前问过这个问题,但大多数回复是针对已知的10位数字进行检查。在我的情况下,数字将是随机的。还有比strspn更好的方法吗?

6 个答案:

答案 0 :(得分:3)

它返回0,因为字符串的开头没有数字。

  

strspn()函数计算的长度(以字节为单位)   s的初始段,完全由accept中的字节组成。

您需要跳过非数字 - strcspn - 然后在字符串+该偏移量上调用strspn。你可以尝试:

/* Count chars to skip. */
skip = strcspn(str_in, cset);

/* Measure all-digit portion. */
length = strspn(str_in + skip, cset)

修改

我应该提到这必须在一个循环中完成。例如,如果您的字符串为"abcd123abcd1234567890",则第一个strspn只会匹配3个字符,您需要进一步查看。

答案 1 :(得分:1)

只需使用sscanf()

unsigned long long value;

const char *str_in = "abcgfg1234567890gfggf";
if(sscanf(str_in, "%*[^0-9]%uL", &value) == 1)
{
  if(value >= 1000000000ull)  /* Check that it's 10 digits. */
  {
   /* do magic here */
  }
}

以上假设unsigned long long足够大以容纳10位十进制数,实际上这意味着它假设是64位类型。

%*[^0-9]转换说明符告诉sscanf()忽略一堆非(十进制)数字的初始字符,然后直接转换无符号长long(%uL)。尾随字符将被忽略。

答案 2 :(得分:0)

替代使用sscanf()

(@unwind的明显变化)

const char *str_in = "abcgfg0123456789gfggf";
int n1 = 0;
int n2 = 0;
// %*[^0-9]  Scan any non-digits.  Do not store result.
// %n        Store number of characters read so far.
// %*[0-9]   Scan digits.  Do not store result.
sscanf(str_in, "%*[^0-9]%n%*[0-9]%n", &n1, &n2);
if (n2 == 0) return 0;
return n2 - n1;

计算前导0个字符作为数字计数的一部分。


是否应该避免sscanf()

char str_in[] = "abcgfg1234567890gfggf";
const char *p1 = str_in;
while (*p1 && !isdigit(*p1)) p1++;
const char *p2 = p1;
while (isdigit(*p2)) p2++;
result = p2 - p1;

答案 3 :(得分:0)

使用正则表达式怎么样?

#include <stdio.h>
#include <stdlib.h>
#include <regex.h>

int
main(int argc, char **argv)
{
    char str_in[] = "abcgfg1234567890gfggf";
    int result = 0;
    const char *pattern = "[0-9]{10}";
    regex_t re;
    char msg[256];

    if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
            perror("regcomp");
            return(EXIT_FAILURE);
    }

    result = regexec(&re, str_in, (size_t)0, NULL, 0);
    regfree(&re);

    if (!result) {
            printf("Regex got a match.\n");
    } else if (result == REG_NOMATCH) {
            printf("Regex got no match.\n");
    } else {
            regerror(result, &re, msg, sizeof(msg));
            fprintf(stderr, "Regex match failed: %s\n", msg);
            return(EXIT_FAILURE);
    }

    return(EXIT_SUCCESS);
}

答案 4 :(得分:0)

strspn似乎很方便,但您必须将其包含在循环中并多次搜索。鉴于具体要求,最简单的方法可能就是制作自己的自定义功能。

int find_digits (const char* str, int n);
/* Searches [str] for a sequence of [n] adjacent digits.
   Returns the index of the first valid substring containing such a sequence,
   otherwise returns -1.
*/


#include <ctype.h>  

int find_digits (const char* str, int n)
{
  int result = -1;
  int substr_len = 0;
  int i = 0;

  for(int i=0; str[i] != '\0'; i++)
  {
    if(isdigit(str[i]))
    {
      substr_len++;
    }
    else
    {
      substr_len=0;
    }

    if(substr_len == n)
    {
      result = i;
      break;
    }
  }

  return result;
}

(我刚刚在这里攻击了这个,现在没有经过测试,但是你明白了。这很可能是这个任务的最快算法,也就是说,如果性能很重要的话)

答案 5 :(得分:0)

在字符串中测试一套“0123456789”你可以做类似的事情:

int             main()
{
  char str_in[] = "abcgfg1234567890gfggf";
  char cset[] = "1234567890";
  int result;
  int i;
  int f;

  i = 0;
  f = 0;
  while (str_in[i])
    {
      if (str_in[i] == cset[f])
        {
          f++;
          if(f == strlen(cset))
            return (f);
        }
      else
        f = 0;
      i++;
    }
}