In C, how can you get an int with leading zeros? - c

I need to generate a pin number, between 0 and 9999;
0's are important since I'm gonna use this pin to encrypt some files, and encrypting with '0024' is different than encrypting with '24'
I'm using an unsigned int and it's isn't working..
Is the only way an array?

You can't. An int is an integer, and for integers it really doesn't make sense to talk about leading zeros. They don't exist, an integer (in the mathematical sense, which is what int is trying to model on a computer) basically cannot have leading zeros. See comments for more pedantry about this, I tried to simplify it reasonably but might have failed since I'm just a lowly programmer and not a mathematician.
All the bits available for the int are used to store actual value bits, none are available to store that kind of representational information.
It sounds as if you want a string, or an array of digits.

Convert your integer value as a string and do formatting so it will return integer with leading zero in string format.

Related

GTK int to unicode char conversion for display in GTK label

I am receiving hex data from a serial port.
I have converted the hex data to corresponding int value.
I want to display the equivalent character over GTK label.
But if we see character map there are control characters from 0x00 to 0x20.
So i was thinking of adding 256 to the converted int value and show the corresponding Unicode character to label.
But i am not able to convert int to Unicode. say if i have an array of ints 266,267,289...
how should i convert it to Unichar and display over GTK label.
I know it may seems very basic problem to you all but i have struggled a lot and didn't find any answer. Please help,
The GTK functions that set text on UI elements all assume UTF-8 strings. A single unsigned byte representing a Unicode code point with value > 127 will not form a valid UTF-8 string if written out as an unsigned byte. I can think of a couple of ways around this.
Store the code point as a 32-bit integer (which is essentially UTF-32) and use the functions in the iconv library, or something similar, to do the conversion from UTF-32 to UTF-8. There are other conversion implementations in C widely available. Converting your unsigned byte to UTF-32 really amounts to padding it with three leading zero bytes -- which is easy to code.
Generate a UTF-8 string yourself, based on the 8-bit code point value. Since you have a limited range of values, this is easy-ish. If you look at the way that UTF-8 is written out, e.g., here:
https://en.wikipedia.org/wiki/UTF-8
you'll see that the values you need to represent are written as two unsigned bytes, the first beginning with binary 110B, and the second with 10B. The bits of the code point value are split up and distributed between these two bytes. Doing this conversion will need a little masking and bit-shifting, but it's not hugely difficult.
Having said all that, I have to wonder why you'd want to assign a character to a label that users will likely not understand? Why not just write the hex number on the label, if it is not a displayable character?

Meaning of character in C's streams

I seem to have a blind spot in my understand of the meaning of character in C's stream abstraction; I just can't seem to stitch the picture together.
What is the meaning of character with respect to binary streams?
From 7.19.7.1p2 ...
If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the stream (if defined).
...
Suppose I wrote a file on machine where characters require 16 bits and I start reading on a machine on which the characters fit in 7 bits. Then what am I actually reading with each call to fgetc? Is it part of the 16 bit character (i.e., I'm reading 7 bits at a time) or is the 16-bit character "squezzed" into a 7 bit representation with information loss?
From the spec:
3.7.1 1 character single-byte character 〈C〉 bit representation that fits in a byte
and:
3.6 1 byte addressable unit of data storage large enough to hold any member of the basic character set of the execution
environment NOTE 1 It is possible to express the address of each
individual byte of an object uniquely. NOTE 2 A byte is composed
of a contiguous sequence of bits, the number of which is
implementation- defined. The least significant bit is called the
low-order bit; the most significant bit is called the high-order bit.
So on your writing machine, char is likely a 16-bit type. On your reading machine, char is likely an 8-bit type. C requires that char be at least an 8-bit type:
5.2.4.2.1 Sizes of integer types
...
— number of bits for smallest object that is not a bit-field (byte)
CHAR_BIT 8
So on your reading machine, you'll need make two fgetc calls to read each half of the 16-bit characters you wrote on the original machine.
Technically, char is a one byte type that can hold values from -128 to 127; depending on the architecture it can also be unsigned, holding values from 0 to 255. But although it is, strictly speaking, an integer type, it is not used to hold integers generally. You will almost always use type int or one of its many variations for that.
Type char, in practice, has a couple of dedicated uses:
It can hold an ASCII value. As there are 128 ASCII codes, or 255 ASCII codes in some extended versions, char is an ideal type for this purpose. But when it is used this way, it nearly always appears in a program as part of a string, which (in C, although not always in C++) is a simple array of char.
If you are designing a structure to be compact, and you want to create a field (that is, a data member) that will never hold more than 256 different values, you might want to use char type for that purpose as well.
Note that there is a subtle point here not always obvious to new C programmers. You can assign ASCII codes to char variables, but that is not really a property of char in C. For example, I could assign ASCII code numbers to any integer field. The C language itself does not prevent this. But remember that C string library functions are designed to be used with arrays of char, not arrays of int.
char* is how you declare a pointer to a char variable. It’s useful when you want a string with unknown length.
1st example:
char name[10];
strcpy (name, "type_your_name_here"); //overwrites the first argument with the second.
Here you’re reserving 10 pieces of memory. You might use them all or your name might just be “Jack” which, if we account for the '\0' special character that comes at the end of every string, takes only 5 memory chunks. That means you have 5 remaining pieces that you’re not using.
Maybe your name is longer that 10 characters, where will you store the extra ones then? You won’t be able to. Because you gave a static declaration to your array of chars.
2nd example:
char *name;
This means that you just declared the pointer variable where you’ll store the address of the first character in your string. It gives more freedom and flexibility to your usage. Whether your name is long or short, the predefined string functions like strcpy and strcat can handle memory allocation for you.
In short:
My understanding is that, in the first example you defined both the starting and end points of your string, which limits what you can fit in there and also can waste memory space. In the second example, you only specified the starting point which grants more usage freedom and memory economy. I don’t know of any drawbacks to the second example, it’s just my first year learning this as well. So may be the experts can shed a brighter light on this matter than I can.

Is subtracting a char by '0' to convert to int bad practice?

I'm expecting a single digit integer input, and have error handling in place already if this is not the case. Are the any potential unforeseen consequences by simply subtracting the input character by '0' to "convert" it into an integer?
I'm not looking for opinions on readability or what's more commonly used (although they wouldn't hurt as an extension to the answer), but simply whether or not it's a reliable form of conversion. If I ask the user to input an integer between 0 and 9, is there any scenario in which there can be input that input = input-'0' should handle, but doesn't?
This is safe and guaranteed by the C language. In the current version, C11, the relevant text is 5.2.1 Character sets, ¶3:
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
As for whether it's "bad practice", that's a matter of opinion, but I would say no. It's both idiomatic (commonly used and understood by C programmers) and lacks any alternative that's not confusing and inefficient. For example nobody reading C would want to see this written as a switch statement with 10 cases or by setting up a dummy one-character string to pass to atoi.
The order of characters are encoding/system-dependent, so one must not rely on a particular order in general. For the sequence of digits 0..9 in any system, however, it is guaranteed that it starts with 0 and continues to 9 without any intermediate characters. So input = input - '0' is perfect as long as you guarantee that input contains a digit (e.g. by using isdigit).

Base conversion from any base to any base in C (up to 36)

im looking for a base conversion function in c that could do conversions from bases 2 up to 36, including bases with characters A-Z.
For now i just found on the web functions that deal with base 2, ten and hex and a bit limited.
For this project, it would probably help to understand how bases work. In any case, let's walk through a process for how one might convert to, say, base twelve. This should be the simplest method to implement.
First up, we have our decimal number, since that's an easy place to start. Let's say, I dunno, 1452 is our number. We'll also need an array of characters for what each character is, since that'll be a lot easier than a straight ASCII conversion, where the number characters and letter characters are separated.
int dec=1452;
int toBase=12;
char outputs[36]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
Following that, we probably will only be OUTPUTTING the result in another base - it doesn't make sense to store it multiple ways, and makes your conversion process simpler by only converting from one base to any other given. We could store the result in a character array, but again, we already have the number stored - no point.
For this method I'm going to describe, we'll need a buffer variable to keep track of our number as we convert parts of it.
int buf=dec;
Next up, we'll start counting spaces back in the base we're going to, 12, and see what each space is worth. We'll continue until we pass our number, then backtrack one. We'll also need to save what space we're on for a for loop from that to the first space later.
int space=0;
while(Math.pow(toBase,space))<buf){
space++;
}//Braces added for clarity
space--;
Now, this is the main calculation loop, where we'll output the result. Again, the original number is still stored in 'dec,' so we don't need to worry about loss of data or changing it at all.
int i;
for(i=space;i>=0;i--){//We have set up the for loop to check each space as we progress
int modResult=buf%Math.pow(toBase,i);//Gets the number that goes in this space of the resulting base number
buf-=modResult*Math.pow(toBase,i);//We have that, so take it out of the number
printf("%c",outputs[modResult]);
}
Because of the way we're doing this, going from the top space to the bottom, modResult will never be higher than the highest number our base can go in. With this, your program will output to console the resulting number. Also, keep in mind that this only outputs the number - for the purposes of storage and calculation, it's much simpler to use the built-in functions that use base 10. Furthermore, be careful that your toBase variable never goes above 36.
As a further note, I numbered the digits (spaces), from right to left, starting at zero, because the far right space is 1, represented by your base to the zeroth power. Hope this helps.

Convert the integer value to hex value

I have this function in xilinx for giving output to Seven segment.
int result;
XIo_Out32(XPAR_SSG_DECODER_0_BASEADDR, result);
The function gets the int result and puts the output to seven segment as a hex value. So basicly, if i give result = 11; I would see A as a result in seven segment. To see a decimal value on sseg, one approach is to change the verilog code behind this and change the whole concept of the sseg. Another approach is to write a function that changes decimal value into a hex value. I've been searching for a good code block for this but it seems that every one of them, prints the values digit by digit with a loop. I need the whole value as a block. Unfortunately i cannot use the C++ libraries so i have primitive C code. Is there any known algorithms for converting?
Apparently, you want to convert symbol codes from ASCII to the ones from the 7-segment display character set. If so, you may create a simple mapping, maybe an array of codes indexed by ASCII character id. Then, you'll be able to call your function like:
XIo_Out32(XPAR_SSG_DECODER_0_BASEADDR, 'A');
Be careful to implement the mapping table for the whole ASCII range.
EDIT
Sorry, I've got your question wrong. You'll have to manually convert hexadecimal number to an array of decimal symbols. You may do it by dividing your number by increasing powers of 10 (10^0, 10^1, 10^2, etc) and thus get an array of remainders, which is a decimal representation of your number. You may use snprintf as H2CO3 recommends, but I would recommend against it in some of the embedded applications where RAM is limited; you may even be unable to use sprintf-like functions at all.

Resources