kolurbo
kolurbo

Reputation: 538

Convert int to ASCII characters in C

How can I convert integer value to ASCII characters in C language? I want to assign characters to array of chars.

char buff[10];

Let's say we have:

int = 93  (HEX: 5D) -> result should be - buff = {']'} 

int = 13398 (HEX: 3456) -> result should be buff = {'4', 'V'}

Similar as is done here

I don't need to care about non printable characters. There will be always printable characters.

Upvotes: 0

Views: 10076

Answers (3)

ryyker
ryyker

Reputation: 23226

convert integer value to ASCII characters in C language?...

Referring to an ASCII table, the value of ']' in C will always be interpreted as 0x5D, or decimal value 93. While the value of "]" in C will always be interpreted as a NULL terminated char array, i.e., a string representation comprised of the values:

|93|\0|  

(As illustrated in This Answer, similar interpretations are valid for all ASCII characters.)

To convert any of the integer (char) values to something that looks like a "]", you can use a string function to convert the char value to a string representation. For example all of these variations will perform that conversion:

char strChar[2] = {0};

sprintf(strChar, "%c", ']'); 
sprintf(strChar, "%c", 0x5D); 
sprintf(strChar, "%c", 93);  

and each produce the identical C string: "]".

I want to assign characters to array of chars...

example of how to create an array of char, terminated with a NULL char, such as "ABC...Z":

int i;
char strArray[27] = {0};
for(i=0;i<26;i++)
{
     strArray[i] = i+'A';
}
strArray[i] = 0;
printf("Null terminated array of char: %s\n", strArray);

Upvotes: 1

Charles Srstka
Charles Srstka

Reputation: 17060

Just use bit-shifting to get the individual bytes.

Assuming an architecture on which the size of int is 4:

int someInt = ...

uint8_t first = (someInt >> 24);
uint8_t second = (someInt >> 16);
uint8_t third = (someInt >> 8);
uint8_t fourth = someInt;

Now you can just put the resulting bytes into your array. Make sure to check first, second and third to make sure they're not 0 first, and skip them if they are. Make sure to end your array with a null terminator, as required by C strings.

This answer assumes big-endian ordering, since that's what you indicated in your example. If you want little-endian, just reverse the order of the bytes when you put them in the array.

Note that this will turn 5DC into 05 and DC. If you want 5D instead, you should check to see whether the first digit in the original int is 0. You can do this using the & operator, testing the int against 0xf0000000, 0x00f00000, etc. If you find the first digit to be 0, shift the int to the right by 4 bits before extracting the bytes from it.

So, something like this:

void ExtractBytes(int anInt, uint8_t *buf, size_t bufSize) {
    // passing an empty buffer to this function would be stupid,
    // but hey, doesn't hurt to be idiot-proof
    if (bufSize == 0) { return; }

    // Get our sizes
    const int intSize = sizeof(anInt);
    const int digitCount = intSize * 2;

    // find first non-zero digit
    int firstNonZero = -1;
    for (int i = 0; i < digitCount; i++) {
        if ((anInt & (0xf << ((digitCount - 1 - i) * 4))) != 0) {
            firstNonZero = i;
            break;
        }
    }

    if (firstNonZero < 0) {
        // empty string; just bail out.
        buf[0] = 0;
        return;
    }

    // check whether first non-zero digit is even or odd;
    // shift if it's odd
    int intToUse = (firstNonZero % 2 != 0) ? (anInt >> 4) : anInt;

    // now, just extract our bytes to the buffer
    int bufPtr = 0;
    for (int i = intSize - 1; i >= 0; i--) {
        // shift over the appropriate amount, mask against 0xff
        uint8_t byte = (intToUse >> (i * 8));

        // If the byte is 0, we can just skip it
        if (byte == 0) {
            continue;
        }

        // always check to make sure we don't overflow our buffer.
        // if we're on the last byte, make it a null terminator and bail.
        if (bufPtr == bufSize - 1) {
            buf[bufPtr] = 0;
            return;
        }

        // Copy our byte into the buffer
        buf[bufPtr++] = byte;
    }

    // Now, just terminate our string.
    // We can be sure that bufPtr will be less than bufSize,
    // since we checked for that in the loop. So:
    buf[bufPtr] = 0;

    // Aaaaaand we're done
}

Now let's take it for a spin:

uint8_t buf[10];

ExtractBytes(0x41424344, buf, 10);
printf("%s\n", buf);

ExtractBytes(0x4142434, buf, 10);
printf("%s\n", buf);

and the output:

ABCD
ABC

Upvotes: 4

alk
alk

Reputation: 70971

unsigned u = ...;

if (0x10 > u)
  exit(EXIT_FAILURE);

while (0x10000 < u) u /= 2;
while (0x1000 > u) u *= 2;

char c[2] = {u / 0x100, u % 0x100);

Upvotes: 0

Related Questions