base 4 to base 2 converter - c

This program is to convert a base 4 number to a base 2 number and it should be done in place
#include<stdio.h>
#include<string.h>
void shiftr(char num[],int i)
{
memmove(num+i,num+i+1,strlen(num)-i);
}
char* convert4to2(char num[])
{
int i=0,len;
char ch;
while(num[i]!='\0')
{
ch=num[i];
shiftr(num,i);
switch(ch)
{
case '0':num[i++]='0';
num[i++]='0';
break;
case '1':num[i++]='0';
num[i++]='1';
break;
case '2':num[i++]='1';
num[i++]='0';
break;
case '3':num[i++]='1';
num[i++]='1';
break;
default:printf("Error");
}
}
num[i]='\0';
return(num);
}
void main()
{
char num[20];
printf("Enter the Base 4 Number:");
scanf("%s",&num);
printf("The Binary Equivalent is:%s\n",convert4to2(num));
}
The output for an input of 121(base 4 number) should be 011001 but its displaying only 01.
And for larger numbers like 12101 it displays 0100 taking the first and the last but one numeral.
What could be the problem?

You're actively destroying your input. E.g., for the first iteration, you shift your number by one place and after that you overwrite the data at place 0 and place 1 (which contains the next 2 digits in 4-base) with your binary output for the 1st digit.

Instead of converting directly from base 4 to base 2 using characters, you could put the string through the strtol function, which converts integer string of arbitrary base to a long. From there it's pretty easy to print out the binary representation.
Edit: Example:
char* convert4to2(const char input[], char *output, const size_t output_length)
{
/* First make sure the output string is long enough */
if (output_length < (sizeof(long) * 8 + 1)) /* +1 for '\0' */
return NULL; /* Not enouth space */
/* Convert from the input string to a `long` */
long value = strtol(input, NULL, 4); /* The last `4` is the base of the input string */
/* Convert the number to binary */
char *output_ptr = output;
/* Multiply with 8 to get the number of bits */
/* Subtract 1 because bits a numbered from zero */
for (int bit = sizeof(long) * 8 - 1; bit >= 0; bit--)
{
/* `value >> bit` make the current bit the lowest bit */
/* `& 1` to mask out all but the lowest bit */
/* `+ '0'` to make it a proper character digit */
*output_ptr++ = ((value >> bit) & 1) + '0';
}
/* Terminate the string */
*output_ptr = '\0';
/* Return the converted string */
return output;
}
Call it like this:
const char num[] = "121";
char output[65]; /* `long` can be 64 bits, plus one for the string terminator */
printf("%s in base 4 is %s in base 2\n",
num, convert4to2(num, output, sizeof(output)));

No need to shift upward, just work backward:
#include <stdio.h>
#include <string.h>
void convert4to2(char *str)
{
size_t idx;
char ch;
static char *conv[4] = {"00", "01","10", "11" };
idx = strlen(str);
str[idx*2] = 0;
while(idx--) {
ch=str[idx];
if (ch < '0' || ch > '3') return; /* replace by relevant error handler */
memcpy(str+2*idx, conv[ ch - '0' ], 2 );
}
return;
}
int main(void)
{
char quad[21] = "0123321023" ;
printf("Old:%s\n", quad);
convert4to2(quad);
printf("New:%s\n", quad);
return 0;
}

Related

How can I send the first and second ascii characters as NULL character in a string and not as "" an empty string?

I am currently dealing with a problem that especially has something to do with the first and second ASCII characters, the NULL Character and SOH Character.
The goal of this code is to send some characters and save them in a Tag, which contains 32 Bits/4 Bytes Blocks where Data can be saved in.
I know that there are better ways to achieve this. My Code functions nearly properly except in one single case:
When the Character equals the first ASCII character NULL. Which means when I view the value of the character: c_Char="", when this get sent to the Tag, it doesnt count as an ascii character and gets skipped.
Which means when I check which Characters are sent, the Buffer does not return the character with the 0 decimal value since it was not saved and got skipped.
Is there any If-Condition that I can use to make my program count the NULL ascii character?
This is part of the main Code:
// Splitting the 32 bits from B0 to 4 Bytes
Daten_EEPROM_Byte_VERTEILER(B0);
// Converting The four 32 Bits/4 Bytes Variables into 4 different decimal numbers
Data_Converting_binary_decimal(cFirst_Byte,&i_Char1);
Data_Converting_binary_decimal(cSecond_Byte,&i_Char2);
Data_Converting_binary_decimal(cThird_Byte,&i_Char3);
Data_Converting_binary_decimal(cFourth_Byte,&i_Char4);
//Converting the 4 decimal numbers into 4 ascii Chars.
Fmt(c_Char1,"%c<%i", i_Char1);
Fmt(c_Char2,"%c<%i",i_Char2);
Fmt(c_Char3,"%c<%i",i_Char3);
Fmt(c_Char4,"%c<%i",i_Char4);
//Converting Ascii characters into hexadecimal numbers.
DATEN_Umwandlungsfunktion_Char_hex (c_Char1, x_char1, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char2, x_char2, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char3, x_char3, &iSeriennummer);
DATEN_Umwandlungsfunktion_Char_hex (c_Char4, x_char4, &iSeriennummer);
//Putting the 4 hex numbers into the one variable:
Fmt(x_Result_B0,"%s<%s%s%s%s",x_char1,x_char2,x_char3,x_char4);
//Showing the 4 hex numbers in a panel:
SetCtrlAttribute(sPanels.P_Hauptmenue, P_MAIN_WB0, ATTR_CTRL_VAL, x_Result_B0);
memset(x_char1,0,sizeof(x_char1));
memset(x_char2,0,sizeof(x_char2));
memset(x_char3,0,sizeof(x_char3));
memset(x_char4,0,sizeof(x_char4));
//Sending the 4 characters into a MSP430 Port to save them in a tag through an antenna
Fmt(Result_Block0,"%s<%s%s%s%s",c_Char1,c_Char2,c_Char3,c_Char4);
Fmt(cCommand,"%s<%s%s%s%s",WRITE_BLOCK,"0_",Result_Block0,ENDE);
// Write and Read Data in and from Block 0
iResult = Befehl_Senden(cCommand,cAnswer);
Fmt(cCommand,"%s<%s%s%s",READ_BLOCK,"0",ENDE);
iResult = Befehl_Senden(cCommand,cAnswer);
CopyBytes(cRead_Block_0,0,cAnswer,23,8);
SetCtrlAttribute(sPanels.P_Hauptmenue, P_MAIN_BR0, ATTR_CTRL_VAL, cRead_Block_0);
These are the following functions that are used to convert the variables:
char *decimal_to_binary(int n)
{
int c, d, t;
char *p;
t = 0;
p = (char*)malloc(32+1);
if (p == NULL)
exit(EXIT_FAILURE);
for (c = 31 ; c >= 0 ; c--)
{
d = n >> c;
if (d & 1)
*(p+t) = 1 + '0';
else
*(p+t) = 0 + '0';
t++;
}
*(p+t) = '\0';
return p;
}
void Daten_HILFSFUNKTION_binary_decimal (char *cEingang, int *iAusgang)
{
int multiplier = 0;
int i;
int sum = 0;
int length;
char cMonth[10] = {0};
int iMonth;
length = StringLength (cEingang);
for (i=length-1; i>=0; i--)
{
CopyBytes (cMonth, 0, cEingang, i, 1);
Fmt (&iMonth, "%x<%s", cMonth);
sum = sum +(iMonth*pow(2, multiplier));
multiplier = multiplier + 1;
}
Fmt (iAusgang, "%i<%i", sum);
}
void Daten_EEPROM_Byte_VERTEILER(char *B)
{
CopyBytes(cFirst_Byte, 0,B,0,8);
CopyBytes(cSecond_Byte, 0,B,8,8);
CopyBytes(cThird_Byte, 0,B,16,8);
CopyBytes(cFourth_Byte, 0,B,24,8);
}
char *Daten_EEPROM_HILFSFUNKTION(char *Char_in_Bits, char *c_8Bits)
{
int Decimal = 0;
char c_Character[5] = {0};
CopyString(Char_in_Bits, 0,c_8Bits,0,8);
Daten_HILFSFUNKTION_binary_decimal (Char_in_Bits, &Decimal);
int B_1_dec = Decimal;
Fmt(c_Character,"%c<%i",B_1_dec);
memset(Char_in_Bits,0,sizeof(Char_in_Bits));
return c_Character;
}
void DATEN_alle_Char_uerbergabe_Funktion (char *Byte_Block,char *c_Char1, char *c_Char2, char *c_Char3,char * c_Char4)
{
DATEN_erster_Char_uebergabe_Funktion(Byte_Block, c_Char1);
DATEN_zweiter_Char_uebergabe_Funktion(Byte_Block, c_Char2);
DATEN_dritter_Char_uebergabe_Funktion(Byte_Block, c_Char3);
DATEN_vierter_Char_uebergabe_Funktion(Byte_Block, c_Char4);
}
char DATEN_erster_Char_uebergabe_Funktion (char *Byte_Block,char *c_Char1)
{
return* c_Char1 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cFirst_Byte);
}
char DATEN_zweiter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char2)
{
return *c_Char2 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cSecond_Byte);
}
char DATEN_dritter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char3)
{
return *c_Char3 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cThird_Byte);
}
char DATEN_vierter_Char_uebergabe_Funktion(char *Byte_Block,char *c_Char4)
{
return *c_Char4 = *Daten_EEPROM_HILFSFUNKTION(Byte_Block, cSecond_Byte);
}
void char_Umwandeln (char *cEingang,char *cAusgang)
{
int ilaenge;
int idez_Wert;
int iPos;
char cZwischenspeicher [5] = {0};
ilaenge = StringLength(cEingang);
for (iPos = 0; iPos <=ilaenge - 1; iPos++)
{
idez_Wert = 0;
//CopyBytes (cZwishcenspeicher, 0, cEingang, ilaenge-iPos,1);
CopyBytes (cZwischenspeicher,0,cEingang,iPos,1);
Scan (cZwischenspeicher,"%s>%i[r256]",&idez_Wert);
if (idez_Wert == 0)
{
CopyBytes (cAusgang, 0,"00",0,2);
}
else if (idez_Wert <16)
{
Fmt(cAusgang,"%s<%s%s%i[r16]",cAusgang,"0",idez_Wert);
}
else
{
Fmt(cAusgang,"%s<%s%i[r16]",cAusgang,idez_Wert);
}
}
StringUpperCase(cAusgang);
}
void DATEN_Umwandlungsfunktion_Char_hex (char *Char, char *hex_Char, int *dec_Nummer)
{
char_Umwandeln (Char,hex_Char);
Scan(&hex_Char,"%s>%x",&dec_Nummer);
}
If anyone has already had this problem and knows a solution for this issue, I would be so thankful. Thanks a lot in advance.

Type casting failure in C program

As a C fresher, I am trying to write a recursive routine to convert a decimal number to the equivalent binary. However, the resultant string is not correct in the output. I think it has to be related to the Type casting from int to char. Not able to find a satisfactory solution. Can anyone help? Thanx in advance.
Code:
#include <stdio.h>
#include <conio.h>
int decimal, counter=0;
char* binary_string = (char*)calloc(65, sizeof(char));
void decimal_to_binary(int);
int main()
{
puts("\nEnter the decimal number : ");
scanf("%d", &decimal);
decimal_to_binary(decimal);
*(binary_string + counter) = '\0';
printf("Counter = %d\n", counter);
puts("The binary equivalent is : ");
puts(binary_string);
return 0;
}
void decimal_to_binary(int number)
{
if (number == 0)
return;
else
{
int temp = number % 2;
decimal_to_binary(number/2);
*(binary_string + counter) = temp;
counter++;
}
}
Should the casting store only the LSB of int in the char array each time?
Do not use global variables if not absolutely necessary. Changing the global variable in the function makes it very not universal.
#include <stdio.h>
char *tobin(char *buff, unsigned num)
{
if(num / 2) buff = tobin(buff, num / 2);
buff[0] = '0' + num % 2;
buff[1] = 0;
return buff + 1;
}
int main(void)
{
char buff[65];
unsigned num = 0xf1;
tobin(buff, num);
printf("%s\n", buff);
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int decimal, counter=0;
//char* binary_string = (char*)calloc(65, sizeof(char));
//C does not allow initialization of global variables with
//non constant values. Instead declare a static char array with 65 elements.
//Alternatively declare binary_string in the main function and allocate memory with calloc.
char binary_string[65];
void decimal_to_binary(int);
int main()
{
puts("\nEnter the decimal number : ");
scanf("%d", &decimal);
decimal_to_binary(decimal);
//*(binary_string + counter) = '\0';
// This is more readable:
binary_string[counter] = '\0';
printf("Counter = %d\n", counter);
puts("The binary equivalent is : ");
puts(binary_string);
return 0;
}
void decimal_to_binary(int number)
{
if (number == 0)
return;
else
{
int temp = number % 2;
//decimal_to_binary(number/2);
//you call decimal_to_binary again before increasing counter.
//That means every time you call decimal_to_binary, the value of count
//is 0 and you always write to the first character in the string.
//*(binary_string + counter) = temp;
//This is more readable
//binary_string[counter] = temp;
//But you are still setting the character at position counter to the literal value temp, which is either 0 or 1.
//if its 0, you are effectively writing a \0 (null character) which in C represents the end of a string.
//You want the *character* that represents the value of temp.
//in ASCII, the value for the *character* 0 is 0x30 and for 1 it is 0x31.
binary_string[counter] = 0x30 + temp;
counter++;
//Now after writing to the string and incrementing counter, you can call decimal_to_binary again
decimal_to_binary(number/2);
}
}
If you compile this, run the resulting executable and enter 16 as a number, you may expect to get 10000 as output. But you get00001. Why is that?
You are writing the binary digits to the string in the wrong order.
The first binary digit you calculate is the least significant bit, which you write to the first character in the string etc.
To fix that aswell, you can do:
void decimal_to_binary(int number){
if(number == 0){
return;
}
else{
int temp = number % 2;
counter++;
//Store the position of the current digit
int pos = counter;
//Don't write it to the string yet
decimal_to_binary(number/2);
//Now we know how many characters are needed and we can fill the string
//in reverse order. The first digit (where pos = 1) goes to the last character in the string (counter - pos). The second digit (where pos = 2) goes to the second last character in the string etc.
binary_string[counter - pos] = 0x30 + temp;
}
}
This is not the most efficient way, but it is closest to your original solution.
Also note that this breaks for negative numbers (consider decimal = -1, -1 % 2 = -1).

Converting negative decimal to two's complement in C

I'm writing a program that, assuming the input is always a valid negative decimal integer, returns the two's complement binary representation (16 bit).
My logic here is that I take in inputs from the command line, and convert that with a simple conversion to binary and add them to the initialized binary array. Then, I take the one's complement (just change 0's to 1's and vise versa) and put that in the onesCom array. However, for the adding 1 part to find the two's complement, I think this is where the issue is but I'm struggling to find it. I am performing binary addition to the least significant bit.
When converting from one-complement to two-complement, i.e. adding 1, your loop should start from the LSB, not from the MSB.
Therefore,
for (j=15; j>=0; j--) { // <-- Error Here
if (onesCom[j] == 1 && carryOver == 1) {
twosCom[j] = 0;
} else if (onesCom[j] == 0 && carryOver == 1) {
twosCom[j] = 1;
carryOver = 0;
} else {
twosCom[j] = onesCom[j];
}
}
Should be replaced by:
for (j=0; j<=15; j++) {
if (onesCom[j] == 1 && carryOver == 1) {
twosCom[j] = 0;
} else if (onesCom[j] == 0 && carryOver == 1) {
twosCom[j] = 1;
carryOver = 0;
} else {
twosCom[j] = onesCom[j];
}
}
In your code, you calculate the one-complement then deduce the two-complement. Please note that it is easier to directly calculate the two-complement, in case you don't need the one-complement, like this:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int binary[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
if (argc == 1) return 1;
int decimal = atoi(argv[1]);
int counter = 0;
if (decimal > -32768 && decimal < 0) {
decimal = 65536 + decimal;
while(decimal > 0) {
binary[counter] = decimal%2;
decimal = decimal/2;
counter++;
}
for (int length = 15; length >=0; length--) {
printf("%d", binary[length]);
}
printf ("\n");
}
return 0;
}
As your snippet is completely blurred, I can only suggest you two approaches to the problem:
The first assuming you are doing two's complement arithmethic all the time, in which case the digit adding must be done with sign.
The second assuming you only parse unsigned values and retaining the sign to make the sign exchange at the end.
Probably both approaches will lead to almost the same efficiency and be compiled into very similar code. I have no preference for any of them.
int decode(char *str, int base)
{
int result = 0,
c,
neg = FALSE;
/* skip whitespace, delete this if you don't
* want to cope with whitespace */
for (; isspace(c = *str); str++) {
continue;
}
if (*str == '-') {
neg = TRUE; /* negative */
str++; /* skip it */
}
/* the next characters might be all digits */
for (; isdigit(c = *str); str++) {
/* multiply by the base */
result *= base;
/* add positive for positives and
* subtract it for negatives */
int d = c - '0'; /* convert c to the digit value */
/* negative if number is negative */
if (neg) d = -d;
/* and add/subtract it */
result = result + d;
}
/* :) got it!! */
return result;
}
and the second approach is:
int decode(char *str, int base)
{
int result = 0,
c,
neg = FALSE;
/* skip whitespace, delete this if you don't
* want to cope with whitespace */
for (; isspace(c = *str); str++) {
continue;
}
if (*str == '-') {
neg = TRUE; /* negative */
str++; /* skip it */
}
/* the next characters might be all digits */
for (; isdigit(c = *str); str++) {
/* multiply by the base */
result *= base;
/* add positive for positives and
* subtract it for negatives */
int d = c - '0'; /* convert c to the digit value */
/* and add/subtract it */
result = result + d;
}
/* :) got it!! */
return neg ? -result : result;
}
Can you see the differences? (hint, I have eliminated one line in the loop and changed one line at the end :) )
If you want to run this code in a full, complete and verifiable example, there's one below, just put one of the above functions in place of the other, and run it.
#include <stdio.h>
#include <ctype.h>
/* these macros are for easy printing, and outputting the file, line and
* function name where the trace is being made */
#define F(_f) __FILE__":%d:%s:"_f, __LINE__, __func__
#define P(_f, ...) printf(F(_f), ##__VA_ARGS__)
/* I use these for portability, as <stdbool.h> is not always available */
#define FALSE (0)
#define TRUE (!FALSE)
int decode(char *str, int base)
{
/* substitute here the body of the function above you want to test */
}
int main()
{
static char *tests[] = {
"0", "-1", "-210", "-211", "-222", "1",
"210", "211", "222", "5400",
/* add more testing cases to your wish */
NULL,
};
int i, passed = 0;
for (i = 0; tests[i]; i++) {
char *test = tests[i];
int expected, actual;
P("Testing '%s' conversion\n", test);
/* expected, decoded with system routines */
if (sscanf(test, "%i", &expected) != 1) {
P("problem scanning %s\n", test);
continue;
}
/* actual, decoded with our function */
actual = decode(test, 10);
char *operator = actual == expected ? "==" : "!=";
P("Test result: actual(%i) %s expected(%i)\n",
actual, operator, expected);
if (actual == expected)
passed++;
}
P("passed %d/%d tests\n", passed, i);
}
Edit
The following code will allow you to easily convert your value to binary:
#define CHK(_n) ((_n) <= sz)
char *to_binary(int p_val, char *buf, size_t sz)
{
CHK(2); /* at least two bytes of buffer space */
buf += sz; /* we start from the end, backwards to avoid having to use
* one bit masks moving all the time around */
*--buf = '\0'; /* this is the last '\0' that should end the string */
sz--; /* update buffer size */
/* we operate better with unsigned, as the
* sign doesn't get involved in shifts (we are reinterpreting
* the sign bit as a normal bit, which makes the assumption that
* integers are stored in two's complement. This is essentially
* nonportable code, but it will work in the stated assumptions. */
unsigned val = (unsigned) p_val;
/* the first below is the second char we check
* above */
do {
*--buf = val & 1 ? '1' : '0';
sz--;
val >>= 1;
} while (CHK(1) && val);
return buf; /* return what we have */
}
And the final main() code looks like this:
int main()
{
static char *tests[] = {
"0", "-1", "-210", "-211", "-222", "1",
"210", "211", "222", "5400",
NULL,
};
int i, passed = 0;
for (i = 0; tests[i]; i++) {
char *test = tests[i];
int expected, actual;
P("Testing '%s' conversion\n", test);
/* expected, decoded with system routines */
if (sscanf(test, "%i", &expected) != 1) {
P("problem scanning %s\n", test);
continue;
}
/* actual, decoded with our function */
actual = decode(test, 10);
char *operator = actual == expected ? "==" : "!=";
char buff[100]; /* temporary variable to hold the
* converted value to binary */
P("Test result: actual(%i/0b%s)\n",
actual,
to_binary(actual, buff, sizeof buff));
P(" %s expected(%i/0b%s)\n",
operator,
expected,
to_binary(expected, buff, sizeof buff));
if (actual == expected)
passed++;
}
P("passed %d/%d tests\n", passed, i);
}

How to rearrange array using spaces?

I'm struggling with rearranging my array. I have used from single to multiple loops trying to put spaces (white characters) between two pairs of characters, but I was constantly rewriting the original input. So there is always an input of even length, for example ABCDEFGH. And my task would be to extend the size of the array by putting spaces after every 2 chars (except the last one).
So the output would be:
AB CD EF GH
So the size of output (if I'm correct) will be (2*input_len)-1
Thanks.
EDIT:
This is my code so far
// output = "ABCDEFGHIJKL
char c1;
char c2;
char c3;
int o_len = strlen(output);
for(int i = 2; i < o_len + olen/2; i = i + 3){
if(i == 2){
c1 = output[i];
c2 = output[i+1];
c3 = output[i+2];
output[i] = ' ';
output[i+1] = c1;
output[i+2] = c2;
}
else{
c1 = output[i];
c2 = output[i+1];
output[i] = ' ';
output[i+1] = c3;
output[i+2] = c1;
c3 = c2;
}
}
So the first 3 pairs are printed correctly, then it is all a mess.
Presuming you need to store the space separate result, probably the easiest way to go about inserting the spaces is simply to use a pair of pointers (one to your input string and one to your output string) and then just loop continually writing a pair to your output string, increment both pointers by 2, check whether you are out of characters in your input string (if so break; and nul-terminate your output string), otherwise write a space to your output string and repeat.
You can do it fairly simply using memcpy (or you can just copy 2-chars to the current pointer and pointer + 1, your choice, but since you already include string.h for strlen() -- make it easy on yourself) You can do something similar to:
#include <stdio.h>
#include <string.h>
#define ARRSZ 128 /* constant for no. of chars in output string */
int main (int argc, char **argv) {
char *instr = argc > 1 ? argv[1] : "ABCDEFGH", /* in string */
outstr[ARRSZ] = "", /* out string */
*ip = instr, *op = outstr; /* pointers to each */
size_t len = strlen (instr); /* len of instr */
if (len < 4) { /* validate at least 2-pairs worth of input provided */
fputs ("error: less than two-pairs to separate.\n", stderr);
return 1;
}
if (len & 1) { /* validate even number of characters */
fputs ("error: odd number of characters in instr.\n", stderr);
return 1;
}
if (ARRSZ < len + len / 2) { /* validate sufficient storage in outstr */
fputs ("error: insufficient storage in outstr.\n", stderr);
return 1;
}
for (;;) { /* loop continually */
memcpy (op, ip, 2); /* copy pair to op */
ip += 2; /* increment ip by 2 for next pair */
op += 2; /* increment op by 2 for next pair */
if (!*ip) /* check if last pair written */
break;
*op++ = ' '; /* write space between pairs in op */
}
*op = 0; /* nul-terminate outstr */
printf ("instr : %s\noutstr : %s\n", instr, outstr);
}
Example Use/Output
$ ./bin/strspaceseppairs
instr : ABCDEFGH
outstr : AB CD EF GH
$ ./bin/strspaceseppairs ABCDEFGHIJLMNOPQ
instr : ABCDEFGHIJLMNOPQ
outstr : AB CD EF GH IJ LM NO PQ
Odd number of chars:
$ ./bin/strspaceseppairs ABCDEFGHIJLMNOP
error: odd number of characters in instr.
Or short string:
$ ./bin/strspaceseppairs AB
error: less than two-pairs to separate.
Look things over and let me know if you have further questions.
Edit To Simply Output Single-Pair or Empty-String
Based upon the comment by #chqrlie it may make more sense rather than issuing a diagnostic for a short string, just to output it unchanged. Up to you. You can modify the first conditional and move it after the odd character check in that case, e.g.
if (len & 1) { /* validate even number of characters */
fputs ("error: odd number of characters in instr.\n", stderr);
return 1;
}
if (len < 4) { /* validate at least 2-pairs worth of input provided */
puts(instr); /* (otherwise output unchanged and exit) */
return 0;
}
You can decide how you want to handle any aspect of your program and make the changes accordingly.
I think you are looking for a piece of code like the one below:
This function returns the output splitted array, as you requested to save it.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char* split_by_space(char* str, size_t length, size_t step) {
size_t i = 0, j = 0, spaces = (length / step);
char* splitted = malloc(length + spaces + 1);
for (i = 0, j = 0; i < length; ++i, ++j) {
if (i % step == 0 && i != 0) {
splitted[j] = ' ';
++j;
}
splitted[j] = str[i];
}
splitted[j] = '\0';
return splitted;
}
int main(void) {
// Use size_t instead of int.
size_t step = 2; // Also works with odd numbers.
char str[] = "ABCDEFGH";
char* new_str;
// Works with odd and even steps.
new_str = split_by_space(str, strlen(str), step);
printf("New splitted string is [%s]", new_str);
// Don't forget to clean the memory that the function allocated.
free(new_str);
return 0;
}
When run with a step value of 2, the above code, outputs:
New splitted string is [AB CD EF GH]
Inserting characters inside the array is cumbersome and cannot be done unless you know the array is large enough to accommodate the new string.
You probably want to allocate a new array and create the modified string there.
The length of the new string is not (2 * input_len) - 1, you insert a space every 2 characters, except the last 2: if the string has 2 or fewer characters, its length is unmodified, otherwise it increases by (input_len - 2) / 2. And in case the length is off, you should round this value to the next integer, which is done in integer arithmetics this way: (input_len - 2 + 1) / 2.
Here is an example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *reformat_with_spaces(const char *str) {
size_t len = strlen(str);
size_t newlen = len > 2 ? len + (len - 2 + 1) / 2 : len;
char *out = malloc(newlen + 1);
if (out) {
for (size_t i = 0, j = 0; i < len; i++) {
if (i > 0 && i % 2 == 0) {
out[j++] = ' ';
}
out[j++] = str[i];
}
out[j] = '\0';
}
return out;
}
int main(void) {
char buf[256];
char *p;
while (fgets(buf, sizeof buf, stdin)) {
buf[strcspn(buf, "\n")] = '\0'; // strip the newline if any
p = reformat_with_spaces(buf);
if (p == NULL) {
fprintf(stderr, "out of memory\n");
return 1;
}
puts(p);
free(p);
}
return 0;
}
Try this,
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void rearrange(char *str)
{
int len=strlen(str),n=0,i;
char *word=malloc((len+(int)(len/2)));
if(word==NULL)
{
printf("Memory Error");
exit(1);
}
for(i=0;i<len;i++)
{
if( i % 2 == 0 && i != 0)
{
word[n]=' ';
n++;
word[n]=str[i];
n++;
}
else
{
word[n]=str[i];
n++;
}
}
word[n]='\0';
strcpy(str,word);
free(word);
return;
}
int main()
{
char word[40];
printf("Enter word:");
scanf("%s",word);
rearrange(word);
printf("\n%s",word);
return 0;
}
See Below:
The rearrange function saves the letters in str into word. if the current position is divisible by 2 i.e i%2 it saves one space and letter into str, otherwise it saves letter only.

How does one convert ASCII to binary?

I have the following string:
char * strIn = "f2";
When I look at strIn[0] I would like to get 1111 instead of 'f'.
How do i do it?
Thanks
You mean a hex string to binary conversion?
strtol with a base of 16 should do the trick
...Someone said earlier
and f in binary would be 11001100
All I can say is wow... no, F in binary equals 1111 (15 decimal)
If I understood your question correctly, you want to get the binary value for any ascii character... ie.
When I look at strIn[0] I would like
to get 1111 instead of 'f'.
So... here is a little function that will do that...
int ConvertHexAsciiValue(char c)
{
if(isalpha(c))
{
char r = tolower(c);
if(r > 'f')
{
// - Handle error here - character is not base 16
return 0;
}
int nIndex = (int)('a' - r);
nIndex = -nIndex;
nIndex += 10;
return nIndex;
}
else if(isdigit(c))
{
int nIndex = c - '0';
return nIndex;
}
// Handle error here - character is not A-F or 0-9
return 0;
}
If I didn't understand you correctly, you should know that you cannot read a string "1111" for a character strIn[0]. You can however, get a binary value for each character (interpreted as a hexidecimal value) using the function I provided...
for(int x = 0; x < strlen(strIn); x++)
{
int val = ConvertHexAsciiValue(strIn[x]);
printf("Value %d: %d\n", x, val);
}
If strIn were set to "f2", this code would produce the following output on the console
Value 0: 15
Value 1: 2
To get the binary code one must take the decimal number in question, take it and divide it by two repeatedly, save the remainder (which will become the binary number), save the whole number, divide by two, and repeat the whole process until 0 is reached.
Heres a small application I had in my collection that converts a string into binary.
/********************************************************/
/* Binary converter */
/* By Matt Fowler */
/* philosopher150#yahoo.com */
/* converts text into binary using the division method */
/* through ASCII code */
/*compiled with the Dev-C++ compiler (www.bloodshed.net)*/
/********************************************************/
#include <iostream>
using namespace std;
#include <cstring>
#include <cstdlib>
char *entry, letter, choice[2];
int ascii, len, binary[8], total;
void prog();
int main()
{
prog();
return 0;
}
void prog()
{
entry = new char[501];
/* entry should be dynamic, otherwise a new string entry of 501 chars would be created each time function is called! Talk about memory hog! */
cout<<"Enter string to convert (up to 500 chars): ";
cin.getline(entry, 500);
len = strlen(entry); /* get the number of characters in entry. */
/* this loop is executed for each letter in the string. */
for(int i = 0; i<len; i++)
{
total = 0;
letter = entry[i]; /* store the first letter */
ascii = letter; /* put that letter into an int, so we can see its ASCII number */
while(ascii>0) /* This while loop converts the ASCII # into binary, stores it backwards into the binary array. */
{
/* To get the binary code one must take the decimal number in
question, take it and divide it by two repeatedly, save
the remainder (which will become the binary number), save
the whole number, divide by two, and repeat the whole
process until 0 is reached. This if-else statement serves
this functionality, by getting the remainder of the ascii
code, storing it in the array and then dividing the int
ascii by two */
if((ascii%2)==0)
{
binary[total] = 0;
ascii = ascii/2;
total++; /* increasing by one each time will yeild the
number of numbers in the array. */
}
else
{
binary[total] = 1;
ascii = ascii/2;
total++;
}
}
total--; /* due to data type factors, the program will actually
add a 0 at the end of the array that is not supposed
to be there, decrementing total will solve this
problem, as that 0 will not be displayed. */
/* this while loop displays the binary code for that letter. */
while(total>=0)
{
cout<<binary[total];
total--;
}
}
delete[] entry; /* free up the memory used by entry */
cout<<endl<<"Do again(1 = yes, 2= no)?: ";
cin.getline(choice,3);
if(choice[0] == '1')
prog(); /* program is recursive, it calls itself. It's kinda
like a function loop of sorts. */
else
exit(0); /* quits the program */
}

Resources