c - 将 long long 存储在 char 数组中而不截断
问题描述
所以我有一个类型的元素数组uint8_t
存储在一个数组中,并且需要基本上将它们连接起来,并生成结果的字符串形式。有没有办法long long
在不截断的情况下存储在 char 数组中?换句话说,如何在 char 数组中存储 64 位?在下面的例子中abacce
,"abacce"
void concat(uint8_t *arr, int size) {
unsigned long long val=0;
for (int i=0; i<size; i++) {
val <<= 8;
val |= arr[i];
}
printf ("%x\n", val); // abacce -- perfect!
// now I need to convert this to a char array since I need to pass this to a function that takes in a char array!! -- below is my failed attempt...
char arr[10];
sprintf(arr, "%x", val); // char = 8 bytes so it truncates the first byte only!
}
int main(void) {
uint8_t arr[] = {0xab, 0xac, 0xce};
concat(arr, sizeof(arr)/sizeof(arr[0]);
}
好的,有人在评论中提到%llx
将存储 long long unsigned 的十六进制表示并在在线 IDE 中,它似乎可以工作,但是当我在 eclipse 中尝试以下操作时,我得到lx
:
void concat(uint8_t *arr, int size, char *str) {
unsigned long long val=0;
for (int i=0; i<size; i++) {
val <<= 8;
val |= arr[i];
}
sprintf(str, "%llx", var); // str has "lx" instead of "0x30abcdababcd"
return val;
}
int main(void) {
char str[20] = {0};
uint8_t arr[] = {0x30, 0xab, 0xcd, 0xab, 0xab, 0xcd};
long long unsigned var = concat(arr, sizeof(arr)/sizeof(arr[0], str);
}
解决方案
您有几个问题应该从 IDE 中跳出来:
sprintf(str, "%llx", var);
var
没有贴花。你的意思是val
。
接下来,由于不匹配,您有一个不完整的表达式'('
:
sizeof(arr)/sizeof(arr[0], str);
不如sizeof arr/ sizeof arr[0]
.
接下来,您尝试void
在上述问题的行中分配类型函数的返回:
long long unsigned var = concat(arr, sizeof(arr)/sizeof(arr[0], str);
您的声明concat()
是:
void concat(...
您不能long long unsigned
从void
. 你想要的是:
unsigned long long concat(uint8_t *arr, int size, char *str)
{
unsigned long long val=0;
for (int i=0; i<size; i++) {
val <<= 8;
val |= arr[i];
}
sprintf(str, "%llx", val); // str has "lx" instead of "0x30abcdababcd"
return val;
}
现在您的代码运行良好。printf
在末尾添加 amain()
以验证 and 的值var
,str
例如
int main(void) {
char str[20] = {0};
uint8_t arr[] = {0x30, 0xab, 0xcd, 0xab, 0xab, 0xcd};
long long unsigned var = concat(arr, sizeof arr /sizeof arr[0], str);
printf ("%llx %s\n", var, str);
}
示例使用/输出
$ ./bin/concatuint8
30abcdababcd 30abcdababcd
您的编译器应该为您提供上述每个错误发生的行。如果不是,那么您正在使用的 IDE 或您的配置方式有问题。在 Linux 或 Windows 中简单地从命令行编译只需不到一秒钟,并且会显示所有启用警告的问题(例如-Wall -Wextra -pedantic -Wshadow
,对于 gcc/clang 或/W3
对于 VS)
看看事情,让我知道如果你有更多的问题。
编辑 2 关于 STM32 F401 微控制器
经过进一步讨论,您正在使用STM32 F401微控制器。在这些或任何微控制器上,您在没有操作系统的“裸机”上编译和运行代码,您正在所谓的独立环境 C11 标准 - 5.1.2.1 独立环境中工作。您使用gcc-eabi
而不是gcc-none-eabi
表明您的目标是微控制器上的某种操作系统。它也可能影响可用的东西。
问题在于,您必须使用的大部分内容都是实现定义的,不一定符合 C 标准。对于具有可以编译和链接的几种不同模式(目标)的手臂板尤其如此。在这里,您有一个thumb
模式和arm
模式,它们会影响使用的寄存器大小以及可用的整数大小。虽然 Cortex-M4 进程将支持ll
,ull
和llu
length 修饰符,但它们可能不适用于所有编译器和链接器模式ARM Compiler Toolchain - long long
您将需要仔细检查您的编译器选项和 IDE 选项,以确保您的目标是支持long long
64 位的构建并使ll
or ull
orllu
修饰符可用。这将来自您正在使用的操作系统Free RTOS
?和编译器文档。gcc ARM 选项解决了编译器选项,但是无论您是在“裸机”上工作还是针对在您的板上运行的某种类型的操作系统,也会有所不同。
这是使用微控制器和嵌入式系统的挑战。除了学习 C 语言之外,您对特定硬件本身也有相同的学习曲线。您需要将您的手臂放在操作系统(如果有的话)与 Cortex-M4 处理器选项一起定位。我建议确定您正在使用的确切操作系统(如果有的话),然后重新提出一个单独的严格定制的问题,类似于“为什么%llx
修改器printf
不能在具有 Cortex M4 处理器的 STM32 F401EE 板上工作”。使用 ARM 标签并查找任何特定于 STM32 板的标签。这将使问题定义在一个水平上,从而邀请具有该特定知识的人来回答。
推荐阅读
- android - 如果没有 @Provides-annotated 方法,就无法提供 Android Hilt。在存储库接口类中
- android - 我想在Android上写一个flutter视频插件。我想通过纹理将它写在kotlin native上
- r - ggplot 热图布局和渐变条
- python - Python pandas:在行中透视DataFrame列
- reactjs - ReactJS 在 UseEffect 中使用 SetInterval 导致状态丢失
- java - 访问子类中的私有超类字段
- regex - 使用 sed 重命名文本文件中的特定行
- javascript - 无法在 if 条件中使用“id”选择器 - JQuery
- java - Http 请求获取 UTC+0 日期而不是 UTC+x 存储在数据库中
- flutter - 如何在 ListView.builder 中从上一个列表停止的位置开始 itemCount?