Arrays 以固定的步频拆分数组并转换为int

Arrays 以固定的步频拆分数组并转换为int,arrays,c,Arrays,C,如何拆分具有3-2-2-2 cadence的9个字符数组,并将其转换为4个不同的int变量 例如: char s[9] = {'9', '8', '7', '6', '5', '4', '3', '2', '1'} a=987; b=65; c=43; d=21; 这里有一个方法: #include <assert.h> #include <stdio.h> static int char_to_digit(char const ch) { assert(ch &

如何拆分具有3-2-2-2 cadence的9个字符数组,并将其转换为4个不同的int变量

例如:

char s[9] = {'9', '8', '7', '6', '5', '4', '3', '2', '1'}
a=987;
b=65;
c=43;
d=21;
这里有一个方法:

#include <assert.h>
#include <stdio.h>

static int char_to_digit(char const ch) {
  assert(ch >= '0' && ch <= '9');
  return ch - '0';
}

static int arr_to_int(char const* arr, int const sz) {
  int res = 0;
  for (int i = 0; i < sz; ++i)
    res = res * 10 + char_to_digit(arr[i]);
  return res;
}

int main() {
  char const s[9] = {'9', '8', '7', '6', '5', '4', '3', '2', '1'};

  int const a = arr_to_int(s, 3);
  int const b = arr_to_int(s + 3, 2);
  int const c = arr_to_int(s + 5, 2);
  int const d = arr_to_int(s + 7, 2);

  printf("%d, %d, %d, %d\n", a, b, c, d);
}
#include

您可以谨慎使用
sscanf()
进行此项工作:

#include <stdio.h>

int main() {
    char s[9] = { '9', '8', '7', '6', '5', '4', '3', '2', '1' };
    int a, b, c, d;

    {  // check that the input data starts with 9 digits
        int n = 0;
        sscanf(s, "%9*[0-9]%n", &n);
        if (n != 9)
            return 1;
    }
    // parse the input data into 4 integers composed of 3, 2, 2 and 2 digits
    if (sscanf(s, "%3d%2d%2d%2d", &a, &b, &c, &d) == 4) {
        printf("%d, %d, %d, %d\n", a, b, c, d);
    }
    return 0;
}

您可以使用
sscanf
来解析即使是没有字符串终止符的字符数组,例如您的字符串,只要您在所有转换说明符中提供最大字段宽度,这样
sscanf
就不会尝试使用数组末尾之后的数据。例如:

char s[9] = {'9', '8', '7', '6', '5', '4', '3', '2', '1'}
int a, b, c, d;

sscanf(s, "%3d%2d%2d%2d", &a, &b, &c, &d);

请注意,字段宽度本身不足以确保数组边界不会溢出,因为
%d
指令也会导致(
s
scanf
使用前导空格。如果字符数据(不是字符串,因为它没有终止)来自外部源,那么您确实应该在解析之前验证其内容。

切勿使用断言。如果代码碰巧是在定义了
NDEBUG
的情况下编译的,
assert()
是不可操作的。首先,中止该过程可能是杀伤力过大。@AndrewHenle我不同意。这是
assert
的预期用例。断言应该用于在调试期间使接口显式,而不是在发布版本中强制执行。不要重复计算10的幂,而是使用以下命令:
static int arr_to_int(char const*arr,int sz){int res=0;for(int i=0;i
有比
assert()
更好的方法来强制执行接口约束。你真的认为在发布版本中放松这些约束可以吗?“是的,我们使用这个版本进行开发和测试,但是我们放松了发行版中的所有约束。什么?它没有日志就失败了?这是不可能的!我们测试了它。哦,是的,没错。我们使用了
assert()
,实际上没有开发和测试我们发行的内容…”对于从用户处获取不正确的输入,正确的响应不是
abort()
。抛弃发布版本中的所有错误检查也是不合适的。三轮车也是用来骑的。这并不能使它们成为成人运输的合适工具<代码>断言()
是一辆三轮车。
char s[9] = {'9', '8', '7', '6', '5', '4', '3', '2', '1'}
int a, b, c, d;

sscanf(s, "%3d%2d%2d%2d", &a, &b, &c, &d);