How does this code convert between bases? - c

#include<stdio.h>
#include<string.h>
void baseconversion(char s[20], int, int);
main()
{
char s[20];
int base1, base2;
printf("Enter the number and base:");
scanf("%s%d", s, &base1);
printf("Enter the base to be converted:");
scanf("%d", &base2);
baseconversion(s, base1, base2);
}
void baseconversion(char s[20], int b1, int b2)
{
int count = 0, r, digit, i, n = 0, b = 1;
for(i = strlen(s) - 1; i >= 0; i--)
{
if(s[i] >= 'A' && s[i] <= 'Z')
{
digit = s[i] - '0' - 7;
}
else
{
digit = s[i] - '0';
}
n = digit * b + n;
b = b * b1;
}
while(n != 0)
{
r = n % b2;
digit = '0' + r;
if(digit > '9')
{
digit += 7;
}
s[count] = digit;
count++;
n = n / b2;
}
for(i = count - 1; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
I know this code converts chars to integers, but I've never seen it before, never used C.
If someone could explain a bit of what's going on with the conversions I'd appreciate it, thank you.
I understand that at some point the digits get reversed.

It does it through two steps, the first one is converting the number into its decimal form, in this part:
for(i = strlen(s) - 1; i >= 0; i--) //Start from right to left
{
if(s[i] >= 'A' && s[i] <= 'Z')
digit = s[i] - '0' - 7; //Get the integer equivalent to the letter
else
digit = s[i] - '0'; //Get the integer equivalent to the numerical character
n = digit * b + n; //Add the value of this character at this position
b = b * b1; //The value of the next character will be higher b times
}
Then it transforms the result to the desired base, in this part:
while(n != 0)
{
r = n % b2; //The remaining will be the rightmost value for the new base
digit = '0' + r; //Get the integer for the new digit
if(digit > '9')
digit += 7; //Here the digit will be a letter
s[count] = digit;
count++;
n = n / b2; //Remove the rightmost digit to get the next one
}

Related

How To Fix Segmentation Fault 11 in a C program?

I am new to C programming. I'm writing a function that converts an integer into hexadecimal.
For some reason, I am getting a segmentation fault 11. Please advise. Thank you!
Here is the code for my function:
it converts the integer to binary first
adds 0s where it is needed so binary length would be multiples of 4
reverses the order of the binary
converts every 4 numbers into hexadecimal
void printHexadecimalForm( int X )
//Purpose: Print parameter X in hexadecimal form
//Output: Hexadecimal representation of X directly printed
//Assumption: X is non-negative (i.e. >= 0)
{
//[TODO] CHANGE this to your solution.
int input = X;
int output[32];
int i = 0;
while(input != 0){
if(input%2 != 0){
input = input - 1;
input /= 2;
output[i] = 1;
i++;
}
else{
input /= 2;
output[i] = 0;
i++;
}
}
while(i % 4 != 0){
output[i + 1] = 0;
i++;
}
for (int j = 0; j < i/2; j++)
{
int temp = output[j];
output[j] = output[i - 1 - j];
output[i - 1 - j] = temp;
}
int c, k = 0;
for(int z = 0; z < i; z += 4; ){
for (c = z; c < c + 4; c++){
k = 10 * k + output[c];
}
if(k == 0000){
printf("%d",0);
}
if(k == 0001){
printf("%d",1);
}
if(k == 0010){
printf("%d",2);
}
if(k == 0011){
printf("%d",3);
}
if(k == 0100){
printf("%d",4);
}
if(k == 0101){
printf("%d",5);
}
if(k == 0110){
printf("%d",6);
}
if(k == 0111){
printf("%d",7);
}
if(k == 1000){
printf("%d",8);
}
if(k == 1001){
printf("%d",9);
}
if(k == 1010){
printf("%c", 'A');
}
if(k == 1011){
printf("%c", 'B');
}
if(k == 1100){
printf("%c", 'C');
}
if(k == 1101){
printf("%c", 'D');
}
if(k == 1110){
printf("%c", 'E');
}
if(k == 1111){
printf("%c", 'F');
}
}
}
I suggest you to take deep breath and start all over again. First remember, there's no need to convert anything to binary. Everything is binary already.
Maybe this little piece, which retrieves two hexadecimal characters could help you to get on to the track: (this is just one method)
int n = 165; // this is the number we want to display in hex (165 is 0xa5)
int i, hexChar;
i = n & 0xF; // bitwise AND with 00...001111
if(i < 10) // look up to ASCII table for more info
hexChar = i + 48; // character '0' is code 48, '1' is 49 etc.
else
hexChar = i + 55; // character 'A' is code 65, 'B' is 66 etc.
printf("Rigth most hex: %c\n", hexChar);
i = n >> 4; // shift all bits 4 steps to the right
i = i & 0xF; // bitwise AND with 00...001111
if(i < 10) // look up to ASCII table for more info
hexChar = i + 48; // character '0' is code 48, '1' is 49 etc.
else
hexChar = i + 55; // character 'A' is code 65, 'B' is 66 etc.
printf("Second hex: %c\n", hexChar);

Why this code error when entering a 4*x symbol number or more? Converting a 16 digit number into 10 digit number

-the program takes the value of the number(16) as a string of char(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)
-transcodes to the correct values ​​according to the character table
-converts values ​​to decimal
but... if:
in: A | out: 10 (+)
in: AA | out: 170(+)
in: AAA| out: ... forget answer but (+)
!!! in: AAAA| out: ERROR (-)
why?
#include <STDIO.H>
#include <CONIO.H>
void main()
{
char m[100]; // init massive chars [m]
gets(m); // input massive [m] (16 digit number)
int i = -1; // init counter for [m] (-1 for start [i++] in 0 pos)
while (m[i++]); // go to last postion in [m] and count length
i--; // step back for skip '\0'
i--; // step back for start position last char
int s = 0; // init sum number (10 digit number)
int v = 1; // init multiplier
while (i >= 0) // it is first char?
{
if ((m[i] >= 'A') && (m[i] <= 'F')) s += ((int)(m[i]-55) * v); // if char 'A'(65) char = (10) * multiplier
else s += ((int)(m[i]) * v); // else char 1,2,3,4,5... (1,2,)* multiplier
v *= 16; // up multiplier power
i--; // char step back
}
printf("%i", s); //out sum
}
after edit after comments:
char m[100];
gets(m);
int i = 0; // * "=-1" -> "0"
while (m[++i]); // * "i++" -> "++i"
i--;
double s = 0; int v = 1;
while (i >= 0)
{
if ((m[i] >= 'A') && (m[i] <= 'F')) s += ((int)(m[i]-55) * v);
if ((m[i] >= '0') && (m[i] <= '9')) s += ((int)(m[i]-48) * v); //add this rules
v *= 16;
i--;
}
printf("%lf", s);
+images with output results
1 & 2
after edit after comments:
char m[100];
gets(m);
for (int i = 0; m[i] != '\0'; i += 1); // *
unsigned long int s = 0; unsigned long int v = 1; // *
for (int u = 0; u < i; u += 1)
{
if ((m[u] >= 'A') && (m[u] <= 'F')) s += ((int)(m[u]-55) * v);
if ((m[u] >= '0') && (m[u] <= '9')) s += ((int)(m[u]-48) * v);
v *= 16;
}
printf("%lu", s); // *
i should start at 0, not -1.
You haven't noticed it yet but your math is wrong for digits 0 through 9.
If you expect all outputs to be positive for 16 Hexidecimal characters you need an unsigned 64-bit integer (however this achieved on your platform/compiler) and you need to print unsigned long (ie not %i/%d).

Spaces and adjacent letters

i have 2 exercises that i need to do i did most but i am stuck now .
for the first one i need the pc to detect spaces and if there is to type incorrect input but idk how can i let the pc detect them .
for the second i need it to type if there are two letters adjacent in the alphabet
example 8#a8d?g.## i need it to type ad . another example 7mK#e*gb!c type (eg) plus if they are already types in the first line then type No such two letters
like b?a0a the first line b?a0a should be the answer and second line if there are 2 letters adjacent (they have same answer)so type No such two letters.
the second question should order the alphabet and if there already is 2 letters in order then type them .
first Qs:-
#include<stdio.h>
#include<conio.h>
#include <math.h>
int main()
{
int a, b, c, d, e, f, decimal;
printf("Enter 5 bits");
scanf("%d", &a);
b = a / 10000;
c = a % 10000 / 1000;
d = a % 1000 / 100;
e = a % 100 / 10;
f = a % 10;
if (b <= 1)
if (c <= 1)
if (d <= 1)
if (e <= 1)
if (f <= 1)
{
f = f*1;
e = e*2;
d = d*4;
c = c*8;
b = b*16;
decimal = b + c + d + e + f;
printf(" your decimal value is %d",decimal);
}
else
{
printf("incorrect output");
}
getch();
2) second Question :-
#include<stdio.h>
#include<string.h>
#include<conio.h>
int main()
{
char string[100];
int length;
int i;
char largest = 96; // Init to a value not in ASCII table
char smallest = 121; // Init to a value not in ASCII table
printf("enter string number ");
scanf("%d", &length);
printf("enter the string ");
scanf("%s", string);
//length = strlen(string);
for (i = 0; i < length; i++) {
if (string[i] >= 'a' && string[i] <= 'z') {
if (string[i] < smallest) {
smallest = string[i];
}
if (string[i] > largest) {
largest = string[i];
}
}
}
for (i = smallest; i <= largest; i++) {
printf("%c", i);
}
printf("\n");
getch();
}
Thanks everyone for your help.

Overwrite a string in C

I'm trying to create a code that converts a decimal into any base between 2 and 16. But I don't know how to write a new value in my string.
void base_conversion(char s[], int x, int b) {
int j, y;
j = 0;
// your code here
while(b > 1 && b < 17) {
if (x < 0) {
x = (-x);
}else if(x == 0) {
s[j] = '\0';
}
x = (x/b);
while(x > 0) {
y = (x%b);
if (y == 10) {
s[j] = 'A';
}else if(y == 11) {
s[j] = 'B';
}else if(y == 12) {
s[j] = 'C';
}else if(y == 13) {
s[j] = 'D';
}else if(y == 14) {
s[j] = 'E';
}else if(y == 15) {
s[j] = 'F';
}else{
s[j] = y;
}
}
}j = j + 1;
}
You were almost there, although several mistakes, so I have "improved" your code. The infinite loop testing the base which needed to be done once only. The while() loops weren't quite organised right - x/b being done outside the digit extraction loop. Another change I made was to use a lookup array to convert each digit to a character, which saves a lot of laborious testing. I also returned the string passed as the function value - might as well add a tad more functionality. In the case of passing a bad base value, I could have returned NULL instead of an empty string. Note also I update j in the same statements where I use it as an index, which makes the code a little more fluent.
#include <stdio.h>
char *base_conversion (char *s, int x, int b) {
char charr[] = "0123456789ABCDEF";
int i, j = 0, len, digit, neg = 0;
*s = 0; // terminate the string passed
if (b < 2 || b > 16) // check the base
return s; // return an empty string
if (x < 0) {
x = -x; // adjust for negative input
neg = 1;
}
do {
digit = x % b; // extract each l.s. digit
s[j++] = charr [digit]; // convert to character
} while (x /= b); // implicitly test for 0
if (neg) // negative input
s[j++] = '-'; // append a minus sign
s[j] = 0; // terminate the string
// reverse the string
len = j;
for (i=0; i<len/2; i++) {
digit = s[i];
s[i] = s[--j]; // pre-decrement j to next char index
s[j] = digit;
}
return s;
}
int main () {
int n;
char strig[65];
for (n=1000; n>=-1000; n-=2000) {
printf ("Binary %d: %s\n", n, base_conversion (strig, n, 2));
printf ("Ternary %d: %s\n", n, base_conversion (strig, n, 3));
printf ("Octal %d: %s\n", n, base_conversion (strig, n, 8));
printf ("Decimal %d: %s\n", n, base_conversion (strig, n, 10));
printf ("Hexadecimal %d: %s\n", n, base_conversion (strig, n, 16));
}
return 0;
}
Program output:
Binary 1000: 1111101000
Ternary 1000: 1101001
Octal 1000: 1750
Decimal 1000: 1000
Hexadecimal 1000: 3E8
Binary -1000: -1111101000
Ternary -1000: -1101001
Octal -1000: -1750
Decimal -1000: -1000
Hexadecimal -1000: -3E8

converting ascii to an interger (C)

I'm brand new to C and i'm working on a method that converts an ascii to an integer. So bascially if i have ABCD (base 16) ill get 43981 (base 10).. Just a short walk through of what i have. I take one digit at i time from the string then that number needs to be translated so i call my chartoint method. Then i think i need to * the pervious result by the base before i add the new number. I am also confused on the printf method. Here is my method so far.
void ascii2int(char *ascii, int base){
int totalstring = 0;
if(2<= base && base <= 16){
for (int i = 0; i < strlen(ascii); i++) {
// Extract a character
char c = ascii[i];
// Run the character through char2int
int digit = char2int(c);
totalstring= digit * base;
printf("%d/n",totalstring);
}
}
}
char2int
int char2int(char digit){
int converted = 0;
if(digit >= '0' && digit <= '9'){
converted = digit - '0';
}
else if( digit >= 'A' && digit <= 'F'){
converted = digit - 'A' + 10;
}
else{
converted = -1;}
return converted;
}
Assuming that function char2int is implemented correctly...
Change this:
totalstring = digit * base;
To this:
totalstring *= base; // totalstring = totalstring * base
totalstring += digit; // totalstring = totalstring + digit
Or to this:
totalstring = totalstring * base + digit;
In addition, call printf outside the for loop (and change that /n to \n).
Solution :
void ascii2int(char *ascii, int base){
//int digit = 0;
int totalstring = 0;
if(2<= base && base <= 16){
for (int i = 0; i < strlen(ascii); i++) {
// Extract a character
char c = ascii[i];
// Run the character through char2int
int digit = char2int(c);
totalstring = totalstring * base + digit;
}
printf("%d", totalstring);
}
}

Resources