【问题标题】:What is the most efficient way to find numbers within a string of other characters?在其他字符的字符串中查找数字的最有效方法是什么?
【发布时间】:2014-06-16 01:07:07
【问题描述】:

由 3 个任意长度的数字组成的字符串 - 嵌入在空格和制表符中,下面用 \t 标记表示:

123456789 \t 12345 \t6789\n

数字之间可以有任意数量的空格和制表符的组合。

例如,这也是有效的:

1    \t \t2\t\t\t\t\t \n3\n  

提取这 3 个数字的最有效方法是什么?

查看sscanf(),但似乎需要字符串的确切格式,对吗?

谢谢。

【问题讨论】:

  • @ghostofstandardspast:这个很好,请输入答案
  • 我其实更喜欢现有的。更重要且可扩展。
  • 删除了令人困惑的'' 序列,因为代码标记使实际空格变得明显。
  • @paxdiablo:好的,很酷。

标签: c linux string algorithm parsing


【解决方案1】:

最明显/最简单的是sscanf

if (sscanf(buffer, "%d%d%d", &v1, &v2, &v3) == 3) {
    /* extracted 3 numbers successfully */

%d 格式说明符跳过空格(包括\t\n 字符),因此变量额外的东西无关紧要。它还会跳过空格,这可能是也可能不是您想要的。

【讨论】:

  • 只是澄清一下,它是否也跳过空格字符,我尝试使用它,但它看起来不正确,但也许我做错了......
  • @P.S.:是的,它会跳过您当前语言环境定义为空格的任何字符。这总是包括空格、制表符、回车和换行符,并且可能包括其他内容(例如 UTF-8 语言环境中各种类型的 unicode 空格)
【解决方案2】:

sscanf() 真的很慢。在ascii中,制表符和空格都是

char* sz = "123456789 \t 12345 \t6789\n"
char* aNum[10] = { 0 };
int cNum = 0;
for (int i=0 ; sz[i] ; ++i) {
  if (sz[i] < '0')
    sz[i] = 0, cNum++;
  else if (!aNum[cNum])
      aNum[cNum] = sz + i;
}

你可以通过更多循环来提高效率

char* sz = "123456789 \t 12345 \t6789\n"
char* aNum[10] = { 0 };
int cNum = 0;
for (int i=0 ; sz[i] ; ++i) {
  if (sz[i] >= '0') {
      aNum[cNum++] = sz + i;
      for ( ; sz[i]>='0' ; ++i) { }
      sz[i] = 0;
  }
}

【讨论】:

  • “sscanf() 真的很慢”取决于许多因素。高级编译器将分析像"%d%d%d" 这样的静态格式字符串,并在编译时形成对strtoi() 的非常有效的调用
  • 我等不及我的编译器开始这样做了!一件事……strtoi 不一定有效。
猜你喜欢
  • 2016-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
相关资源
最近更新 更多