0

我需要将int值转换为char字符串,我使用了以下函数,其中 score 的类型为int

void updateScore(){
   char str[5] = "0";
   sprintf(str, "%d", score);
   drawString(str);
}

void drawString5x7(char *string){
   while (*string) 
      drawChar5x7(*string++);
}

这似乎可行,除了这段代码是一个更大的系统的一部分,我在一个可用内存空间有限的微控制器 (MSP430) 上编写视频游戏。我可以在我的游戏死机和崩溃之前更新一次分数。

出于某种原因,每当我添加sprintf()函数(或其他类似函数,如snprintf, 或asprintf)时,它都会占用 MCU 上的大量可用内存。

使用sprintf它编译的函数为11407 字节。如果我注释掉那一行,我的代码编译为4714 字节

我对转换intchar字符串不太熟悉,但是,我认为它不应该消耗那么多内存。任何指导将不胜感激。

4

4 回答 4

1

这是我intstring功能的快速实现:

// buf - string buffer, e.g. 16 bytes
// len - size of buf
// value - integer value
char * i2s( char * buf, int len, int value )
{
    char m = 0;

    if ( value < 0 )
    {
        // if ( value == -2147483648 ) return "-2147483648"; // fix for INT_MIN
        value = -value;
        m = '-'; // minus for negative values
    }
    buf[len - 1] = 0; // 0 for end of string
    for ( int i = len - 2; i > 0; i-- ) // loop from right (last digits) to left
    {
        buf[i] = '0' + ( value % 10 );
        value /= 10;
        if ( value == 0 )
            break;
    }
    if ( m ) buf[--i] = m;
    return buf + i;
}

用法:

char my_buf[16];

char * s = i2s( my_buf, sizeof my_buf, 10850 ); // 10850 is the int value
于 2017-04-26T07:53:01.793 回答
0

五个字符并不多 - 要涵盖一个 int 的每个值,您至少需要 10 个数字 + 符号 + 终止 0 个字符,即 12。然后我将创建一个大小为 2 的数组,所以 16:

char str[16];

然后你可以简单地从后面编码:

str[sizeof(str)] = 0;
char* pos = str + (sizeof(str) - 1);
int n = score < 0 ? -score : score;
do // do while handles n == 0 correctly!
{
    // possible, if all digits are placed one after another
    // in ascending order, such as in ASCII (and those based on):
    *--pos = '0' + n % 10;
    // alternative, portable over all encodings:
    //*--pos = "0123456789"[n % 10];
    n /= 10;
}
while(n);
if(score < 0)
    *--pos = '-';

drawString(pos);

编辑(查看写我的时发布的其他答案(和评论)):

上述解决方案也将失败INT_MIN

你可以单独捕捉这个(score == INT_MIN)——或者简单地依赖这个永远不会达到的值(因为在你的游戏中不合理)。

另外:我的输出是左对齐的!如果你想要右对齐的输出,你可以简单地在 for 循环中放置额外的空格:

for(char* align = str + 4; pos > align;)
    *--pos = ' ';

请注意,您不能将任意指针与<, >, <=, >=! 在这里,这是可能的,因为两个指针都指向同一个数组!

于 2017-04-26T08:06:36.940 回答
0

已经发布了一个通用解决方案。在您的情况下,在已知上限和下限的情况下,您可以使用以下代码:

void updateScore() {
   char str[5] = "0";     /* Can hold up to 4 digits. */
   int i, div = 1000; /* 10^(length of str - 2). */
   int sc = score;
   /* Fast-forward to the first non-zero digit */
   while (div > sc) {
     div /= 10;
   }
   for (i = 0; div; i++) {
     str[i] = ´0´ + sc / div;
     sc %= div;
     div /= 10;
   }
   drawString(str);
}

如果你想用 0 填充分数,你不需要快进到第一个非零数字:

void updateScore() {
   char str[5] = "0";     /* Can hold up to 4 digits. */
   int i, div = 1000; /* 10^(length of str - 2). */
   int sc = score;
   for (i = 0; div; i++) {
     str[i] = ´0´ + sc / div;
     sc %= div;
     div /= 10;
   }
   drawString(str);
}
于 2017-04-26T07:53:20.517 回答
0

您可以手动打印整数,例如

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

void drawChar ( char c )
{
    printf("%c", c);
}

void drawScore(uint16_t score)
{
    bool startFound = false;
    uint16_t devider = 1000;

    while (devider != 0)
    {
        uint8_t digit = (score / devider);

        if (( digit == 0) && (startFound == false))
        {
            // draw space
            drawChar(0x20);
        }
        else
        {
            // first digit of score found
            startFound = true;

            // draw space
            drawChar(digit+'0');
        }

        // move to the next digit
        score -= digit * devider;
        devider /= 10;
    }
}

int main(void)
{
    drawScore(1234);
    printf("\n");
    drawScore(234);
    printf("\n");
    drawScore(34);
    printf("\n");
    drawScore(4);
    printf("\n");
}

linux终端上的输出。

1234
 234
  34
   4
于 2017-04-26T07:54:57.673 回答