Padding and adding binary strings in C - c

I have been tasked with writing a program in C that takes strings of binary digits and adds them. The two strings can be different lengths, so before they are added, they need to be padded to the same size.
//Make copy of strings with proper padding
char *aCopy = (char *)calloc(size+1,sizeof(char));
char *bCopy = (char *)calloc(size+1,sizeof(char));
int i;
for(i = size; i >= 0; i--)
{
aCopy[i] = '0';
bCopy[i] = '0';
}
for (i = strlen(a); i >= 0; i--)
if (i == 0 && a[i]=='1') //Two's complement
aCopy[i] = '1';
else
aCopy[size - i] = a[strlen(a)-i];
for (i = strlen(b); i >= 0; i--)
if (i == 0 && b[i]=='1') //Two's complement
bCopy[i] == '1';
else
bCopy[size - i] = b[strlen(b)-i];
I am having an issue where, if the lines commented "Two's complement" are run (they serve to move the leading 1 digit to the front of the padded string), the length of the padded string becomes one more than it should be. I cannot figure out why this is happening, and it is screwing up my calculations.
Edit: To clarify, an extra '0' char is being added to the end of the two's complement string.

Related

Something's wrong with my reverse string function

So it seems it works when I reversed "hello", but it prints out something weird like
"ol▒eh"
in the middle. It's gone when I fixed
i< length/2;
to
i<= length/2;
Isn't the first one supposed to be the right one?
what's the ▒ character mean in C? is it something like Null?
void reverse_copy(char dest[], const char src[]){
size_t i;
char temp;
size_t length = (size_t)strlen(src);
for(i = 0; i <= length/2; i++){ /*?? why i<length/2 is not working*/
dest[i] = src[length-i-1];
temp = src[i];
dest[length-i-1] = temp;
}
}
The main problem with i< length/2; is that it may leave out the "middle" element in case of odd string lenght of src. Hence, the middle element in dest may remain uninitialized, showing up as some "arbitrary" ASCII value then.
But in general, your code is appropriate for reverse_in_place, where you have to take care of not overwriting something that you need later in the loop for copying.
If you do a reverse_copy, however, it is sufficient - or better - to simply have one reverse loop:
void reverse_copy(char dest[], const char src[]){
size_t i;
size_t length = strlen(src);
for(i = 0; i < length; i++){
dest[i] = src[length-i-1];
}
dest[i] = '\0';
}
With :
for(i = 0; i < length/2; i++){
you never set the middle character (for odd lengths) in dest.
With your example "hello", length/2 is 2, so you set (for i = 0) :
dest[0] = src[5-0-1]; // dest[0] = src[4]
dest[5-0-1] = src[0]; // dest[4] = src[0]
and then (for i = 1) :
dest[1] = src[5-1-1]; // dest[1] = src[3]
dest[5-1-1] = src[1]; // dest[3] = src[1]
and that's it. You never set dest[2].
Because i<length/2 is already based on integer division, i.e: it will floor the result. This will skip the middle element in case of odd length strings.
To understand what is happening in the code, a debugger would help.
You need to step through the code line by line and watch what is the value of i and length - i - 1.
The reason a strange character appears in the middle is that if length is odd then the middle item is skipped when the condition is <.
For example, when length == 5 then 5/2 == 2 (because of integer division 2.5 comes out to be 2 ).
So analysing the loop:
i=0
is i < 2. Yes, so continue code block.
dest[0] = src[4]
temp = src[0]
dest[4] = temp
i++ i is 1
is i < 2. Yes, so continue code block.
dest[1] = src[3]
temp = src[1]
dest[3] = temp
i++ i is 2
is i < 2. No, so exit the loop
So looking at the steps (especialialy steps 3,5,8,10) only dest[0], dest[1], dest[3], dest[4] are written from the source when checking <.
Destination 2 is not changed.
This problem does not arise for even numbers.
As dest[2] was not updated then the character which was already there, is been displayed. Which could be any random character. If it was initialized to 0 (a null) then that is the character that represents 0.
But looking at that character it looks more like a value 177 (extended ASCII codes :http://www.asciitable.com/)
Also I find this definition of reverse_copy very error prone, as it it doesn't know how big the destination buffer is. It can overwrite something if it is too small.
In this case I would use a sentinel to mark the end of the string, and use a while loop:
void reverse_copy(char dest[], const char src[])
{
const char* src_end = src + strlen(src) - 1;
--src;
while (src_end > src)
{
*dest = *src_end;
++dest;
--src_end;
}
*dest = '\0';
}

Binary to UTF-8 in C

I am working on an application in C where I need to show Unicode UTF-8 characters. I am getting the values as a binary byte stream as 11010000 10100100 as character array which is the Unicode character "Ф".
I want to store and display the character. I tried to convert the binary to a hexadecimal character array. But printing with
void binaryToHex(char *bData) {
char hexaDecimal[MAX];
int temp;
long int i = 0, j = 0;
while (bData[i]) {
bData[i] = bData[i] - 48;
++i;
}
--i;
while (i - 2 >= 0) {
temp = bData[i - 3] * 8 + bData[i - 2] * 4 + bData[i - 1] * 2 + bData[i];
if (temp > 9)
hexaDecimal[j++] = temp + 55;
else
hexaDecimal[j++] = temp + 48;
i = i - 4;
}
if (i == 1)
hexaDecimal[j] = bData[i - 1] * 2 + bData[i] + 48;
else if (i == 0)
hexaDecimal[j] = bData[i] + 48;
else
--j;
printf("Equivalent hexadecimal value: ");
char hexVal[MAX];
// size_t len = j+1;
int k = 0;;
while (j >= 0) {
char *ch = (char*)hexaDecimal[j--];
if (j % 2 == 0) {
hexVal[k] = '\\';
k++;
hexVal[k] = 'x';
k++;
}
printf("\nkk++Length %d ...J= %d.. ", k, j);
hexVal[k] = ch;
k++;
printf("%c", ch);
}
printf("KKKK+=== %d", k);
hexVal[k] = NULL;
// printf("\nkk++Length %d",strlen(hexVal));
printf("\nMM+-+MM %s===\n ..>>>>", hexVal);
}
Only showing the value as \xD0\xA4. I did string manipulation for that.
But when writing in the way
char s[]= "\xD0\xA4";
OR
char *s= "\xD0\xA4";
printf("\n %s",s);
producing the desired result that is printing the character "Ф". How can I get the correct string dynamically? Is there any library for this in C?
The code is from http://www.cquestions.com/2011/07/binary-to-hexadecimal-conversion-in.html.
Is there a way to print it from binary directly or from a HEX value. Or is there an alternative for that?
Escape codes such as \xD0 are interpreted by the compiler when encountered in the value of a character or string literal. The compiler replaces them with the corresponding byte (or byte sequence in some cases). They are not meaningful to C at runtime.
You are therefore not only making it harder on yourself but doing altogether the wrong thing by constructing and printing the text of such escape sequences at runtime. What you get is exactly what you should expect. Just print the literal byte sequence you decode from the program input, without any dress-up.
At last converting the Unicode binary char array to actual binary codepoint like converting
11010000 10100100 to 10000 100100 and then converting to decimal and then to Unicode solved my problem for now.below is the link I use to convert to UTF8 from decimal.
C++ Windows decimal to UTF-8 Character Conversion
resources I used:
https://www.youtube.com/watch?v=vLBtrd9Ar28
http://www.zehnet.de/2005/02/12/unicode-utf-8-tutorial/

Create char array from int in C

How do you put an int into a char array?
int x = 21, i = 3;
char length[4];
while(i >= 0) {
length[i] = (char) (x % 10);
x /= 10;
i--;
} printf("%s\n", length);
// length should now be "0021"
The string comes out blank instead.
Note: This is not a duplicate of "How do I convert from int to chars in C++?" because I also need padding. i.e. "0021" not "21"
You're not getting the character code of the digit, you're using the digit as if it were its own character code. It should be:
length[i] = '0' + (x % 10);
You also need to add an extra element to the length array for the terminating null character:
char length[5];
length[4] = 0;
The problem in your code is basically that 1 != '1' i.e. the character is not the integer, you need to check the ascii table to see what ascii code represents the character '1' but you don't really need to know the number, you can just use '1' note the single qoutes.
But you also didn't nul terminate your string, you need to add a '\0' at the end of the string, so
int x = 21, i = 3;
char length[5];
length[4] = '\0';
while (i >= 0)
{
length[i--] = x % 10 + '0';
x /= 10;
}
printf("%s\n", length);
should work, but is unecessary, you can just
snprintf(length, sizeof(length), "%0*d", padding, x);
/* ^ this is how many characters you want */
notice that sizeof works because length is a char array, do not confuse that with the length of a string.

strToInt function convert list of characters to integer in C

In C, I need a function that takes an alphanumerical list characters from 0-9 and converts it to an integer.
Code:
int strToInt(char string[])
{
int i, intValue, result = 0;
for (i = 0; string[i] > '0' && string[i] <= '9'; ++i)
{
intValue = string[i] - '0';
result = ???
}
return result;
}
What do I put in the ??? to make it work?
Try this:
result = result * 10 + intValue;
Also:
string[i] > '0'
in the for loop seems nasty - numbers can contain the digit 0, right? You may want to use
string[i] >= '0'
instead, or even better, without reinventing the wheel:
#include <ctype.h>
for (i = 0; isdigit(string[i]); ++i)
Well, your string is in decimal, base 10, and each digit in the string represents a position in a base 10 system. I.e. So you'd want to do
result = result * 10 + intValue;
Remember that '0' is also a digit, so you don't want to omit that one, Use string[i] >= '0'
If you are talking about base 10, you should probably include 0 also as a digit and hence
string[i] >= '0'
in your for loop. and usual place value calculation
result = result*10 + intValue;

Convert char in char array to its own char array in ANSI C

I have a char array representing a double precision floating point number in hex form.
char *hex = ""402499999999999A"
I want to extract each char in hex as its own char array and read it into an unsigned int num. For example, I tried
sscanf((char *)&hex[3], "%X", &num);
But this doesn't give me the 4th char as an individual char array, it gives me the sub char array from the 4th position on, which I suppose is because arrays are given by the pointer of their first element.
Is there a better way to do this? I looked at strcpy and it seems that I can only copy the first n chars, so that's no good.
You can do this in many ways. One way is as follows (which is the correct way of how you were doing it):
char only_1_char[2] = {'\0', '\0'};
only_1_char[0] = hex[3];
sscanf(only_1_char, "%X", &num);
and a more efficient solution:
if (hex[3] <= '9')
num = hex[3] - '0';
else
num = hex[3] - 'A' + 10;
This is just a sample, though. In truth you need to take care of invalid input and lower cases if that is a possibility.
Try something like this:
for(i = 0; src[i] != 0; i++) {
if(src[i]) <= '9') {
dest[i] = src[i] - '0';
} else {
dest[i] = toupper(src[i]) - 'A' + 10;
}
}
It can be improved with error handling (e.g. detect if "src[i]" contains a valid/sane character).

Resources