0

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.

14
  • 5D (in Hex) is ']'.... Not sure what you want to do with the trailing 'C'...You might want to be more clear how you intend to handle multiple char values in an int Commented Dec 29, 2017 at 16:58
  • When transforming 5DC to ']'. Where is the C gone. Commented Dec 29, 2017 at 16:58
  • @alk It should be done same way as here So it takes always 8 bites and if there is less as 8 bites left it returns nothing. Commented Dec 29, 2017 at 17:07
  • What about 0x10000? Commented Dec 29, 2017 at 17:16
  • How do you know that 1500 should be {']'} and not {'\x05', '\xDC'}? Commented Dec 29, 2017 at 17:18

3 Answers 3

4

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 
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. This seems to be right solution but I would like to do it automatically... Is there any built in function?
@Joozty There are a few tricks that will seem to work, but when you actually try them, they won't. For example, you could use memcpy with a pointer to your int and copy that into your string, but if you're on a little-endian architecture (and you probably are), that'll turn 0x12345678 into { 0x78, 0x56, 0x34, 0x12 }. You could use the appropriate function for your platform's API to swap the int to big-endian first, but then you're still not going to get that last digit removed like you want. Honestly, it's easiest just to do it yourself, IMO.
@Joozty I fleshed it out for you a bit; check the edit.
Curious, why no & 0xff in uint8_t first = (someInt >> 24); like the next 3 lines of code? If someInt == -1 then someInt >> 24 would still have 24 upper bits to ignore. IAC, It is unnecessary for any of the 4.
@chux You're right; since they're being stored in a uint8_t, that'll all be chopped off anyway. I've been doing a lot of Swift lately, where trying to store something larger than what the type can hold causes a runtime error rather than just chopping it off, and it's a bit in my head at the moment (and the first one would have needed to be masked too anyway; that's my bad. I was thinking of what I typically do with unsigned integers). I've edited the answer; thanks.
|
1

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); 

Comments

0
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); 

2 Comments

What about bigger numbers DEC(1212696648), HEX(48484848) - ASCII(FFFF)?
@Joozty: Answering to my questions you commented to treat 0x10000 the same as 0x100000 as 0x1000000 ....

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.