3

我有这样的功能stoi

static int *stoi(const char *c) {
    int *r = new int[2];
    r[1] = sscanf(c, "%d", &r[0]);
    return r;
}

例如,当我给出c = "a5"时,它不起作用。

当我给c = "543336535"时,它起作用了。

但是当我给c = "45sdfff-sdbsdf esg5sq4f"它时,它会返回r[0] = 45,我不希望那样,因为45...之后有一些非数字字符

我只希望我的函数读取纯数字字符串。

4

2 回答 2

5

为了对您已有的代码进行最小的更改,您可以使用以下%n功能sscanf

int chars_read;
r[1] = sscanf(c, "%d%n", &r[0], &chars_read);

如果chars_read小于字符串的长度,sscanf则不消耗所有字符,因此字符串不完全由单个整数组成。

Linux 文档scanf指出,技术勘误 1引入的附加示例与标准相矛盾,但与此同时,标准已更新以解决冲突。sscanf面对您可能遇到的不确定的实现行为,您可以如何解释结果:

switch (r[1]) {
  case EOF: // empty string
    break;
  case 0: // doesn't start with numeric characters
    break;
  case 1: // starts with number; sscanf follows standards
  case 2: // starts with number; sscanf follows TC1
    if (c[chars_read] == '\0')
      r[1] = 1; // we read entire string
    else
      r[1] = 0; // didn't read entire string; pretend we read nothing
    break;
  default: // shouldn't happen
    assert(FALSE);
}
于 2012-05-17T17:23:13.930 回答
3

如果您使用的是 C,您可以使用 Cstrtol来执行您可能称之为暂定转换的操作。它会给你一个指向它可以转换的数据结尾的指针。如果那不是字符串的结尾,那么在它可以转换的任何内容之后至少有一些垃圾。

如果您使用 C++,您可能想要使用 Boost lexical_cast,如果整个输入转换为目标类型,它将成功,但如果其中任何一个没有转换,则抛出异常。

于 2012-05-17T17:24:06.107 回答