从 char 数组转换为 16 位有符号整数和 32 位无符号整数
Convert from char array to 16bit signed int and 32bit unsigned int
我正在为我开发的 PCB 开发一些嵌入式 C,但是我的 C 有点生锈了!
我正在寻找从 char 数组到各种整数类型的一些转换。
第一个例子:
[input] " 1234" (note the space before the 1)
[convert to] (int16_t) 1234
第二个例子:
[input] "-1234"
[convert to] (int16_t) -1234
第三个例子:
[input] "2017061234"
[convert to] (uint32_t) 2017061234
我试过使用 atoi(),但似乎没有得到预期的结果。有什么建议吗?
[编辑]
这是转换代码:
char *c_sensor_id = "0061176056";
char *c_reading1 = " 3630";
char *c_reading2 = "-24.30";
uint32_t sensor_id = atoi(c_sensor_id); // comes out as 536880136
uint16_t reading1 = atoi(c_reading1); // comes out as 9224
uint16_t reading2 = atoi(c_reading2); // comes out as 9224
尝试像这样初始化您的字符串:
char c_sensor_id[] = "0061176056";
char c_reading1[] = " 3630";
char c_reading2[] = "-24.30";
几件事:
- 切勿使用
atoi
系列函数,因为它们没有错误处理功能,并且如果输入格式不正确可能会崩溃。相反,请使用 strtol
系列函数。
- 这些函数中的任何一个在资源受限的微控制器上都占用了大量资源。您可能需要推出自己的
strtol
. 版本
示例:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
int main()
{
const char* c_sensor_id = "0061176056";
const char* c_reading1 = " 3630";
const char* c_reading2 = "-1234";
c_reading1++; // fix the weird string format
uint32_t sensor_id = (uint32_t)strtoul(c_sensor_id, NULL, 10);
uint16_t reading1 = (uint16_t)strtoul(c_reading1, NULL, 10);
int16_t reading2 = (int16_t) strtol (c_reading2, NULL, 10);
printf("%"PRIu32 "\n", sensor_id);
printf("%"PRIu16 "\n", reading1);
printf("%"PRId16 "\n", reading2);
}
输出:
61176056
3630
-1234
观察到的行为非常令人惊讶。我建议编写函数将字符串转换为 int32_t
和 uint32_t
并使用它们代替 atoi()
:
uint32_t atou32(const char *s) {
uint32_t v = 0;
while (*s == ' ')
s++;
while (*s >= '0' && *s <= '9')
v = v * 10 + *s++ - '0';
return v;
}
int32_t atos32(const char *s) {
while (*s == ' ')
s++;
return (*s == '-') ? -atou32(s + 1) : atou32(s);
}
没有错误处理,甚至不支持 +
,但至少该值被转换为 32 位,如果类型 [=16=,则 atoi()
不会出现这种情况] 在你的目标平台上只有 16 位。
我正在为我开发的 PCB 开发一些嵌入式 C,但是我的 C 有点生锈了!
我正在寻找从 char 数组到各种整数类型的一些转换。
第一个例子:
[input] " 1234" (note the space before the 1)
[convert to] (int16_t) 1234
第二个例子:
[input] "-1234"
[convert to] (int16_t) -1234
第三个例子:
[input] "2017061234"
[convert to] (uint32_t) 2017061234
我试过使用 atoi(),但似乎没有得到预期的结果。有什么建议吗?
[编辑]
这是转换代码:
char *c_sensor_id = "0061176056";
char *c_reading1 = " 3630";
char *c_reading2 = "-24.30";
uint32_t sensor_id = atoi(c_sensor_id); // comes out as 536880136
uint16_t reading1 = atoi(c_reading1); // comes out as 9224
uint16_t reading2 = atoi(c_reading2); // comes out as 9224
尝试像这样初始化您的字符串:
char c_sensor_id[] = "0061176056";
char c_reading1[] = " 3630";
char c_reading2[] = "-24.30";
几件事:
- 切勿使用
atoi
系列函数,因为它们没有错误处理功能,并且如果输入格式不正确可能会崩溃。相反,请使用strtol
系列函数。 - 这些函数中的任何一个在资源受限的微控制器上都占用了大量资源。您可能需要推出自己的
strtol
. 版本
示例:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
int main()
{
const char* c_sensor_id = "0061176056";
const char* c_reading1 = " 3630";
const char* c_reading2 = "-1234";
c_reading1++; // fix the weird string format
uint32_t sensor_id = (uint32_t)strtoul(c_sensor_id, NULL, 10);
uint16_t reading1 = (uint16_t)strtoul(c_reading1, NULL, 10);
int16_t reading2 = (int16_t) strtol (c_reading2, NULL, 10);
printf("%"PRIu32 "\n", sensor_id);
printf("%"PRIu16 "\n", reading1);
printf("%"PRId16 "\n", reading2);
}
输出:
61176056
3630
-1234
观察到的行为非常令人惊讶。我建议编写函数将字符串转换为 int32_t
和 uint32_t
并使用它们代替 atoi()
:
uint32_t atou32(const char *s) {
uint32_t v = 0;
while (*s == ' ')
s++;
while (*s >= '0' && *s <= '9')
v = v * 10 + *s++ - '0';
return v;
}
int32_t atos32(const char *s) {
while (*s == ' ')
s++;
return (*s == '-') ? -atou32(s + 1) : atou32(s);
}
没有错误处理,甚至不支持 +
,但至少该值被转换为 32 位,如果类型 [=16=,则 atoi()
不会出现这种情况] 在你的目标平台上只有 16 位。