【问题标题】:Convert integer to char array function将整数转换为字符数组函数
【发布时间】:2014-06-21 17:07:58
【问题描述】:

我想在没有任何预定义 C/C++ 函数(例如 itoa)的情况下将数字转换为非零终止字符数组。 我没有太多空间了(在一个总共 5KB pgm 空间的嵌入式应用程序上工作,我已经使用了 4.862KB)并且我的输出函数不接受以零结尾的字符数组;只有一个数组和长度。

编辑 1:我不是为公司工作:P

编辑 2:不接受意味着如果数组中有一个 0 字节,它将无缘无故地发送。

编辑 3:我使用下面“来自莫斯科的弗拉德”的方法的修改版本解决了这个问题。仍然感谢所有尝试帮助我的人:)

编辑 4:如果有人关心:该项目正在使用蓝牙设置基于 AVR 的闹钟。

【问题讨论】:

  • 好的,你试过了吗?
  • 提示您入门,i + '0' 其中i 是一个以 10 为基数的单个数字,将为您提供该数字的 ASCII/UTF8 字符。
  • @mafso 大多数嵌入式系统的 UART 输出硬件/接口在字节上工作,而不是 C 字符串。因此,您为它们编写的低级输出函数采用任意字节数组和长度而不是字符串是合乎逻辑的。这让你可以传递整数、浮点数、字符串,只要它是一个字节数组。当然,您在接收端的解释功能仍然需要知道传入的数据代表什么。
  • @muessigb 如果你设计了这个协议,你为什么选择以文本格式传输数字?!?那可能是一个糟糕的决定:/ ...啊,顺便说一句,便宜的人给出了一些答案...
  • @πάνταῥεῖ 是正确的。如果您要发送混合格式的数据并且您总是要在终端中将其打印出来,那么我可以理解转换为字符串,因此它需要是一个字符串。但是如果它需要是一个字符串,它需要在某个时候以零结尾。如果它没有被假定为 c 字符串的东西接收到,那么对于任何大于 999 的数字(因为您有 1 字节的标头开销),直接将值作为数字发送更节省空间。将最大 32bit-int 表示为文本需要 10 个字节而不是 4 个。

标签: c++ c arrays char


【解决方案1】:

由于我的小时费率等于零 $(我失业),那么我将展示一种可能的方法。:)

在我看来,最简单的方法是编写递归函数。例如

#include <iostream>

size_t my_itoa( char *s, unsigned int n )
{
    const unsigned base = 10; 
    unsigned digit = n % base;
    size_t i = 0;

    if ( n /= base ) i += my_itoa( s, n );

    s[i++] = digit + '0';

    return i;
} 

int main() 
{
    unsigned x = 12345;
    char s[10];

    std::cout.write( s, my_itoa( s, x ) );

    return 0;
}

输出是

12345

虽然我使用了unsigned int,但您可以修改函数使其接受 int 类型的对象。

如果你需要在函数中分配字符数组,那么它会更简单,并且可以是非递归的。

【讨论】:

  • 谢谢。我会试试你的。我刚刚为此写了一个函数,但你的似乎更小。
  • @vlad-from-moscow 如果您目前处于失业状态,那将是一个更好的理由,为此要钱。但是,您已经知道我们对这个网站的最终区别是什么。祝你好运,你在这里获得的代表,以某种方式有助于提升你的职业生涯。
  • 再次感谢,您的功能可以在我的项目中使用 :) 很高兴您免费提供帮助;这只是一个(大部分)对我来说的小项目,无论如何我不会从中得到一分钱,所以为什么要投资一个;)
  • +1 得到很好的回答和使用size_t。次要:可以使用if ( n /= base ) i = my_itoa( s, n );=+=.
【解决方案2】:

通用算法:

除非我知道嵌入式系统施加的堆栈限制(例如 PIC 的堆栈深度非常有限)以及您当前的堆栈使用情况,否则我个人不能推荐递归算法。

原始数字 = 145976

newnumber = orignumber 

newnumber = new number / 10
remainder = new number % 10    answer: 6
digit = remainder + 30 hex -> store into array  answer:0x36  ascii 6
increment array location

newnumber = new number / 10
remainder = new number % 10    answer: 7
digit = remainder + 30 hex -> store into array  answer:0x37  ascii 7
increment array location

newnumber = new number / 10
remainder = new number % 10    answer: 9
digit = remainder + 30 hex -> store into array  answer:0x39  ascii 9
increment array location

repeat these 4 steps while new number > 0  

Array will contain: 0x36 0x37 0x39 0x35 0x34 0x31
null terminal array, 

空终止允许轻松计算字符串长度和字符串反转。 另一种选择是通过递减指针来从末尾填充数组以避免反转字符串。

Array will contain: 0x36 0x37 0x39 0x35 0x34 0x31 0x00
finally reverse array

Array will contain: 0x31 0x34 0x35 0x39 0x37 0x36 0x00

【讨论】:

  • 你不需要计算字符串长度;您可以简单地将指针从开头减去结尾,以找出您的循环存储了多少位。或者不是反转,而是存储从缓冲区的 end 开始的数字,就像在 How do I print an integer in Assembly Level Programming without printf from the c library? 中的 C 和 x86 asm 函数中一样(如果你要复制到其他地方,最有用,所以可以使用字符串,不管它从哪里开始。)
猜你喜欢
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多