-1

so I am trying to convert some integers in to character arrays that my terminal can write. so I can see the value of my codes calculations for debugging purposes when its running. as in if the int_t count = 57 I want the terminal to write 57. so char* would be an array of character of 5 and 7

The kicker here though is that this is in an freestanding environment so that means no standard c++ library. EDIT: this means No std::string, no c_str, no _tostring, I cant just print integers.

The headers I have access to are iso646,stddef,float,limits,stdint,stdalign, stdarg, stdbool and stdnoreturn

Ive tried a few things from casting the int as an const char*, witch just led to random characters being displayed. To feeding my compiler different headers from the GCC collection but they just keeped needing other headers that I continued feeding it until I did not know what header the compiler wanted.

so here is where the code needs to be used to be printed.

uint8_t count = 0;
while (true)
{
    terminal_setcolor(3);
    terminal_writestring("hello\n");

    count++;

    terminal_writestring((const char*)count);
    terminal_writestring("\n");
}

any advice with this would be greatly appreciated.

I am using an gnu, g++ cross compiler targeted at 686-elf and I guess I am using C++11 since I have access to stdnoreturn.h but it could be C++14 since I only just built the compiler with the latest gnu software dependencies.

skyline
  • 51
  • 9

2 Answers2

1

Without C/C++ Standard Library you have no options except writing conversion function manually, e.g.:

template <int N>
const char* uint_to_string(
    unsigned int val,
    char (&str)[N],
    unsigned int base = 10)
{
    static_assert(N > 1, "Buffer too small");
    static const char* const digits = "0123456789ABCDEF";

    if (base < 2 || base > 16) return nullptr;

    int i = N - 1;
    str[i] = 0;

    do
    {
        --i;
        str[i] = digits[val % base];
        val /= base;
    }
    while (val != 0 && i > 0);

    return val == 0 ? str + i : nullptr;
}

template <int N>
const char* int_to_string(
    int val,
    char (&str)[N],
    unsigned int base = 10)
{
    // Output as unsigned.
    if (val >= 0) return uint_to_string(val, str, base);

    // Output as binary representation if base is not decimal.
    if (base != 10) return uint_to_string(val, str, base);

    // Output signed decimal representation.
    const char* res = uint_to_string(-val, str, base);

    // Buffer has place for minus sign
    if (res > str) 
    {
        const auto i = res - str - 1;
        str[i] = '-';
        return str + i;
    }
    else return nullptr;
}

Usage:

char buf[100];
terminal_writestring(int_to_string(42, buf));      // Will print '42'
terminal_writestring(int_to_string(42, buf, 2));   // Will print '101010'
terminal_writestring(int_to_string(42, buf, 8));   // Will print '52'
terminal_writestring(int_to_string(42, buf, 16));  // Will print '2A'
terminal_writestring(int_to_string(-42, buf));     // Will print '-42'
terminal_writestring(int_to_string(-42, buf, 2));  // Will print '11111111111111111111111111010110'
terminal_writestring(int_to_string(-42, buf, 8));  // Will print '37777777726'
terminal_writestring(int_to_string(-42, buf, 16)); // Will print 'FFFFFFD6'

Live example: http://cpp.sh/5ras

Rost
  • 8,779
  • 28
  • 50
  • This is very nice!​​​​ – Lightness Races in Orbit Jan 23 '17 at 13:49
  • This is Perfect. (except I have a feeling it might not work with negative numbers i am yet to test that though) at first I had to manually go through each line and comment in my own words what it dose before I finally worked it out what it did. however theres still one part I dont understand and that is int N and eavey thingthat goes with it `(&str)[N], int i = N-1, static_assert(N > 1, "Buffer too small");` Im assuming that that is the part that splits 42 in to 4 and 2 but how I do not understand. – skyline Jan 24 '17 at 09:21
  • Yes, this function will not work with negatives, as the question mentioned uintX_t types as target. But it's easy to improve it so it will work with negatives as well. – Rost Jan 24 '17 at 09:31
  • char (&str)[N] means "param 'str' is reference to array of chars of length N". N is template parameter, so array of any length can be passed to function and N will be deducted automatically by compiler. Static assert checks that array is at least 2 chars long to keep valid zero-terminated string. int i = N-1 means we start filling that array from end,not from beginning (as we don't know final string length at start). – Rost Jan 24 '17 at 09:34
  • so dose that then mean that a buffer of 100 (witch btw i dont think ill have interges the size of an googol :p) would not be any slower then an buffer of 50 since the compiler automatically deducts the size of the array to N? also where dose N get its value? has to some how come from the length of val but val is an T how dose it get the length of an T value? – skyline Jan 24 '17 at 11:03
  • Yes, any buffer size wouldn't slow down function performance. N gets the value in compile time, it's constant. Compiler does it when encounters function call with specific buffer type (of length 50, 100, 150 etc). Buffer size isn't related directly to the length of T, it's chosen empirically, as we know that e.g. 100 chars is guaranteed enough to store any integer number of standard type (up to 64 bit long). – Rost Jan 24 '17 at 11:12
  • Out of curiosity how would you rewrite it to support Negative numbers? I was thinking of that you could use an if<0 branch to do an different calculation for negative numbers but I want to see what you were thinking when you said its easy to improve. – skyline Jan 24 '17 at 12:46
  • See updated code. Unfortunately without `type_traits` standard header it's not so easy to write generic function, so sticking to `int` and `unsigned int`pair only to keep it simple and avoid too much street template magic. – Rost Jan 24 '17 at 21:38
-2

You could declare a string and get the pointer to it :

std::string str = std::to_string(count);
str += "\n";
terminal_writestring(str.c_str());
fzd
  • 765
  • 1
  • 6
  • 19
  • 1
    _"The kicker here though is that this is in an freestanding environment so that means no standard c++ library. The headers I have access to are iso646,stddef,float,limits,stdint,stdalign, stdarg, stdbool and stdnoreturn"_ – Lightness Races in Orbit Jan 23 '17 at 12:18