【问题标题】:Iterate through string and store numbers in array遍历字符串并将数字存储在数组中
【发布时间】:2017-08-20 12:55:49
【问题描述】:

我喜欢遍历字符串1.3.6.1.2.1.2.2.1.10.1 并将所有数字存储在一个数组中。我的代码适用于 0-9 之间的数字,但不适用于大于 9 的数字,因为我只迭代一步并扫描数字。如何存储所有数字,而不是像我当前的输出:1 3 6 1 2 1 2 2 1 10 0 1(没有换行符)?

int main(int argc, char *argv[])
{
    //char * string = "1.3.6.1.2.1.2.2.1.9.1"; /* OK */
    char * string = "1.3.6.1.2.1.2.2.1.10.1"; /* NOK */
    static int oid_val_arr[256];
    char *oid_tmp = string;
    int idx = 0;
    while (*oid_tmp)
    {
        int number;
        if (sscanf(oid_tmp, "%d", &number) == 1)
        {
            oid_val_arr[idx] = number;
            idx++;
        }
        oid_tmp++; /* PROBLEM */
    }

    for(int i = 0; i < 12; i++)
        printf("%d\n", oid_val_arr[i]);
}

我应该使用strtok()吗?

【问题讨论】:

  • 扫描成功后,您可以添加oid_tmp += log(oid_val_arr[idx]);
  • @alk 你能解释一下你的意思吗?我不明白。
  • while(isdigit(*oid_tmp)) { oid_tmp++; } if(*oid_tmp == '.') { oid_tmp++; } 这需要#include &lt;ctype.h&gt;
  • log10() 的文档在这里:port70.net/~nsz/c/c11/n1570.html#7.12.6.8;文档日志对数在这里:en.wikipedia.org/wiki/Logarithm
  • 忘记strtok。使用 strtol 代替 scanf;它会给出一个指向第一个不匹配字符的指针。

标签: c string token


【解决方案1】:

在你的代码中,改变这个:

if(sscanf(oid_tmp, "%d", &number) == 1)

到这里:

if(sscanf(oid_tmp, "%d%n", &number, &len) == 1)

为了得到长度。那么当然你需要像这样改变你的while循环:

while (*oid_tmp)
{
    int number;
    int len;
    if(sscanf(oid_tmp, "%d%n", &number, &len) == 1)
    {
        oid_val_arr[idx++] = number;
        oid_tmp += len;
    }
    else
    {
        ++oid_tmp;
    }
}

正如 BLUEPIXY 所说。


另一种方法是使用strtok()atoi(),如下所示:

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

#define SIZE 11

int main ()
{
  int arr[SIZE], i = 0; 
  char str[] ="1.3.6.1.2.1.2.2.1.10.1";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str,".");
  while (pch != NULL)
  {
    //printf ("%s\n",pch);
    arr[i++] = atoi(pch);
    pch = strtok (NULL, ".");
  }
  for(i = 0; i < SIZE; ++i)
      printf("%d ", arr[i]);
   printf("\n");
  return 0;
}

输出:

Splitting string "1.3.6.1.2.1.2.2.1.10.1" into tokens:
1 3 6 1 2 1 2 2 1 10 1

【讨论】:

    【解决方案2】:

    或代替 strtok

    函数忽略数字之间的多个分隔符。

    int stringToIntArray(const char *string, char *separators, int *table, size_t tablesize, int ignoreinvalid)
    {
        int result = (string == NULL || separators == NULL || table == NULL || !tablesize) * -1;
        char tmpbuff[50];
        char *tmpptr;
        int invalid = 0;
    
    
        if (!result)
        {
            while (*string)
            {
                invalid = 0;
                tmpptr = tmpbuff;
                while (*string && strchr(separators, *string) != NULL)  string++;
                while (*string && strchr(separators, *string) == NULL)
                {
                    if (isdigit(*string)) *tmpptr++ = *string;
                    else
                    {
                        if (ignoreinvalid == 1)
                        {
                            invalid = 1;
                            break;
                        }
                        if (ignoreinvalid == 2)
                        {
                            result = -1;
                            break;
                        }
                    }
                    *string++;
                }
                if (result != -1)
                {
                    if (invalid)
                    {
                        while (*string && strchr(separators, *string) == NULL) string++;
                    }
                    else
                    {
                        *tmpptr = '\0';
                        if (!strlen(tmpbuff)) break;
                        table[result++] = atoi(tmpbuff);
                        if (result == tablesize) break;
                    }
                }
                else break;
            }
        }
        return result;
    }
    

    用法:

    int ar[11];

    int cnt = stringToIntArray("123,:0dddd3:0:;456", ",:;", &ar, 11, 0);
    

    最后一个参数 - 0 忽略无效符号,1 忽略数字,2 中断扫描并出现错误。返回找到的数字数量或错误时返回 -1

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 2016-03-09
      • 2014-04-06
      • 2018-08-17
      • 2015-09-09
      • 2014-06-16
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多