在C++中使用sscanf从字符串中提取int

Using sscanf to extract an int from a string in C++

本文关键字:字符串 提取 int C++ sscanf      更新时间:2023-10-16

我的函数必须处理看起来像say hello y(5)或data|x(3)|的字符串,并且我需要能够提取所显示的整数并将其存储到一个名为address的单独int变量中。但是,一些通过的字符串将没有任何整数,并且对于这些字符串,地址必须默认为0。当字符串包含整数时,它将始终位于括号之间。我尝试过使用sscanf,但是,作为sscanf的新手,我遇到了一些问题。。由于某种原因,地址总是读作0。这是我的代码:

void process(string info)
{
int address = 0; // set to 0 in case info contains no digits
sscanf(info.c_str(), "%d", address);
.
.
.
// remainder of code makes other function calls using the address, etc
}

关于为什么sscanf找不到括号之间的整数,有什么想法吗?谢谢

为什么sscanf无法找到括号之间的整数

一旦检测到非数字序列,sscanf(info.c_str(), "%d", address)中的"%d"将导致sscanf()停止扫描。像"(5)"这样的文本将简单地在"("处停止扫描。

相反,代码需要跳过非数字文本。


伪码

  in a loop
    search for any of "-+0123456789"
    if not found return 0
    convert from that point using sscanf() or strtol()
    if that succeeds, return number
    else advance to next character

样本代码

int address;
const char *p = info.c_str();
for (;;) {
  p += strcspn(p, "0123456789+-");
  if (*p == 0) return 0;
  if (sscanf(p, "%d", &address) == 1) {
    return address;
  }
  p++;
}

注:

strcspn函数计算由s1指向的字符串的最大初始段的长度,该最大初始段完全由非由s2指向的字符串组成。C11 7.24.5.3 2


如果代码希望依赖于"它将始终在括号之间。"输入(如"abc()def(123)")不会出现,因为()之间有前面的非数字数据。:

const char *p = info.c_str();
int address;
if (sscanf(p, "%*[^(](%d", &address)==1) {
  return address;
}
return 0;

或简称

int address = 0;
sscanf(info.c_str(), "%*[^(](%d", &address);
return address;

您可以使用这样简单的方法,其中strchr查找第一个出现的"(",然后使用atoi返回将停止在第一个非数字处的整数。

  char s1[] = "hello y(5)";
  char s2[] = "data [x(3)]";
  char s3[] = "hello";
  int a1 = 0;
  int a2 = 0;
  int a3 = 0;
  char* tok = strchr( s1, '(');
  if (tok != NULL)
    a1 = atoi(tok+1);
  tok = strchr( s2, '(');
  if (tok != NULL)
    a2 = atoi(tok+1);
  tok = strchr(s3,'(');
  if (tok != NULL)
    a3 = atoi(tok+1);
  printf( "a1=%d, a2=%d, a3=%d", a1,a2,a3);
  return 0;

当字符串包含整数时,它将始终介于括号

要严格遵守这一要求,您可以尝试:

void process(string info)
{
    int address;
    char c = '5'; //any value other than ) should work
    sscanf(info.c_str(), "%*[^(](%d%c", &address, &c);
    if(c != ')') address = 0;
    .
    .
    .
}

链接到解决方案

int address;
sscanf(info.c_str(), "%*[^0-9]%d", &address);
printf("%d", address);

这应该提取括号

之间的整数