I am working on an assignment for a C Programming course in regards to converting a decimal to binary using a function that takes in an unsigned char as its input and has a void output. The function will print the binary code of the unsigned char. A hint for the assignment is to create an array of exponents starting with 128 and going down to 1.
I started working on the assignment and ran the debugger, but my program is not working and I am getting a run time error message: Run-Time Check Failure #2 - Stack around the variable userInput was corrupted.
I would appreciate some suggestions on how I can fix my code and if there is a much simple way to write it in order to make the code easier to understand.
#include <stdio.h>
#include <stdlib.h>
unsigned char DecimalToBinary(unsigned char decimalInput);
void main() {
unsigned char userInput = ' ';
unsigned char resultOfUserInput = DecimalToBinary(userInput);
printf("Enter a number less than 256: ");
scanf_s("%u", &userInput);
printf("%u in binary: %u", userInput, resultOfUserInput);
system("pause");
}
unsigned char DecimalToBinary(unsigned char decimalNumber) {
int arrayOfExponents[128] = {}, i = 1, j;
while (decimalNumber > 0) {
arrayOfExponents[i] = decimalNumber % 2;
i++;
decimalNumber = decimalNumber / 2;
}
for (j = i - 1; j > 0; j--) {
printf("%i", arrayOfExponents[j]);
}
return 0;
}
%u reads an unsigned int (say 4 bytes) and you are trying to read it into variable userInput (1 byte)
Few things
1) scanf_s("%u", &userInput); please change it to scanf_s("%c", &userInput);
2) You are calling DecimalToBinary before reading user input
#include <stdio.h>
#include <stdlib.h>
unsigned DecimalToBinary(unsigned char decimalInput);
int main(void) {//void is invalid as a return value.
unsigned userInput = 256;
unsigned resultOfUserInput;//DecimalToBinary(userInput);userInput did not input at this point.
printf("Enter a number less than 256: ");
if(1 != scanf_s("%u", &userInput)){
printf("invaid input!\n");
return EXIT_FAILURE;
}
if(userInput >= 256){
printf("More than 256 of the value has been entered.\n");
return EXIT_FAILURE;
}
resultOfUserInput = DecimalToBinary((unsigned char)userInput);
printf("%u in binary: %u\n", userInput, resultOfUserInput);
system("pause");
return 0;
}
unsigned DecimalToBinary(unsigned char decimalNumber) {
unsigned bin = 0, exp = 1;//assert(sizeof(unsigned) >= 4);
while (decimalNumber > 0) {
bin += (decimalNumber & 1) * exp;
decimalNumber >>= 1;
exp *= 10;
}
return bin;
}
This is an easy way to convert numbers from base 10 to any other base using recursion. I have shared one example with you. You can have any other number as your base.
#include <stdio.h>
void baseconvert(int number,int base)
{
if(number > 0)
{
int digit = (number % base);
baseconvert(number / base, base);
printf("%d",digit);
}
else
{
printf("\n");
}
}
int main()
{
baseconvert(1023,2);
return 0;
}
Related
For some reason the program is not working when I try to run it and I can't figure it out. I'd appricate any help. Homework stuff, so I have to stick to the very basics.
#include <stdio.h>
long long int decimal(long long int);
int power_2 (int);
long int power_10 (int);
int main(void){
long long int n;
while(1){
printf("Write down a binary number. \n");
scanf("%lld", &n);
long long int a = decimal(n);
printf("The binary number %lld converted into decimal is: %lld \n", n, a);
}
}
//Here what I realized is if let's say I have the number 1001, then I subtract 1 and divide by 10, the remainder is going to be 0, meaning it will "jump" on the second if statement. I don't really know how to solve it.
long long int decimal(long long int e){
long long int result;
long long int k = 0;
int i;
for(i=0; i>=0; i++){
if(e % 10 == 1){
k += power_2(i);
e--;
if(e != 0){
e /= 10;
}
}
if(e % 10 == 0){
e /= 10;
if(e==0){
break;
}
}
return(k);
}
//This function should work, so it's not a problem
int power_2(int n){
int base = 2, i, result = 1;
if(n>0){
for(i=1; i<=n; i++){
result *= base;
}
}
if(n=0){
result = 1;
}
return(result);
}
//This is just something I thought I would need but no
long int power_10(int n){
int base = 10, i, result = 1;
if(n>0){
for(i=1; i<=n; i++){
result *= base;
}
}
if(n=0){
result = 1;
}
return(result);
}
You can't use scanf with %lld to input a binary number string (e.g. 10101010101010101010101010101010101). It will interpret the number incorrectly.
You have to accept it as a char string (e.g).
char str[100];
scanf("%s",str);
But, scanf is problematic because it can overflow str. And, IMO, the "usual" remedy of:
scanf("%99s",str);
Is a hack [because if we ever change to (e.g.) char str[80]; then we have to manually change the scanf as well].
Better to use fgets:
char str[100];
fgets(str,sizeof(str),stdin);
str[strcspn(str,"\n")] = 0;
Then, loop on the string. No need for power* functions. You want:
long long int decimal(const char *e){
Loop on e and do: k <<= 1;
Here is the refactored code:
#include <stdio.h>
#include <string.h>
long long int
decimal(const char *e)
{
long long int result = 0;
for (int chr = *e++; chr != 0; chr = *e++) {
result <<= 1;
switch (chr) {
case '0':
case '1':
result += (chr - '0');
break;
default:
fprintf(stderr,"decimal: not a binary digit -- chr='%c'\n",chr);
break;
}
}
return result;
}
int
main(void)
{
char str[100];
while (1) {
printf("Write down a binary number.\n");
if (fgets(str,sizeof(str),stdin) == NULL)
break;
// strip newline
str[strcspn(str,"\n")] = 0;
long long int a = decimal(str);
printf("The binary number '%s' converted into decimal is: %lld (hex: %llX)\n",
str, a, a);
}
return 0;
}
Here is some sample output:
Write down a binary number.
110010111001
The binary number '110010111001' converted into decimal is: 3257 (hex: CB9)
Write down a binary number.
UPDATE:
Apart from the possibility of "overfilling" the register with bits (accepting a string that is more than 32 or 64 'bits'), someone here on SO recently pointed out that left shifting (possibly into the sign bit) a "signed" value can invoke UB... –
Fe2O3
I'm not sure it's UB (depending on the context). But, to keep the peace, here's a version that sets errno:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifndef UNSIGNED
#define UNSIGNED 0
#endif
#if UNSIGNED
typedef unsigned long long num_t;
#define FMT "%llu"
#else
typedef long long num_t;
#define FMT "%lld"
#endif
num_t
decimal(const char *e)
{
int count = 0;
long long int result = 0;
errno = 0;
// NOTE: use of error codes is arbitrary
for (int chr = *e++; chr != 0; chr = *e++) {
result <<= 1;
if (++count > (63 + UNSIGNED)) {
fprintf(stderr,"decimal: too many digits\n");
errno = E2BIG;
break;
}
switch (chr) {
case '0':
case '1':
result += (chr - '0');
break;
default:
fprintf(stderr,"decimal: not a binary digit -- chr='%c'\n",chr);
errno = EINVAL;
break;
}
if (errno)
break;
}
return result;
}
int
main(void)
{
char str[100];
while (1) {
printf("Write down a binary number.\n");
if (fgets(str,sizeof(str),stdin) == NULL)
break;
// strip newline
str[strcspn(str,"\n")] = 0;
num_t a = decimal(str);
printf("The binary number '%s' converted into decimal is: " FMT " (hex: %llX)\n",
str, a, a);
}
return 0;
}
Caveat: The following is off topic for this question, but, in response to the comments below ...
Neither of those, although... No, the DV for braces (not an anonymous drive-by shooting!) was for stackoverflow.com/a/74010599/17592432, the most trivial game on the planet... :-) /sigh/ –
Fe2O3
I agree that leaving off the curly braces is not ambiguous. But, I would add them for human clarity. Note that GNU indent complains about premature EOF when trying to indent the code.
But, I eschew if/else ladder logic. In your block, using an if and then switch/case would be clearer, IMO.
And, I've never liked else if because to me, to properly indent it, we'd have:
if (user == robot)
printf("It's a tie!");
else
if (user == 1)
if (robot == 2)
printf("Robot wins by choosing Paper!");
else
printf("User wins by choosing Rock!");
else
if (user == 2)
if (robot == 1)
printf("User wins by choosing Paper!");
else
printf("Robot wins by choosing Scissors! ");
else
if (user == 3)
if (robot == 2)
printf("User wins by choosing Scissors!");
else
printf("Robot wins by choosing Rock!");
So, [to further muddy the waters] I prefer using do { ... } while (0):
do {
if (user == robot) {
printf("It's a tie!");
break;
}
if (user == 1) {
if (robot == 2)
printf("Robot wins by choosing Paper!");
else
printf("User wins by choosing Rock!");
break;
}
if (user == 2) {
if (robot == 1)
printf("User wins by choosing Paper!");
else
printf("Robot wins by choosing Scissors! ");
break;
}
if (user == 3) {
if (robot == 2)
printf("User wins by choosing Scissors!");
else
printf("Robot wins by choosing Rock!");
break;
}
} while (0);
UPDATE #2:
May at least want to mention POSIX and _t types (I'm guilty as charged on the use as well) –
David C. Rankin
Sigh, I was hoping to have a quiet day ;-)
First, I like [love] POSIX (vs. ISO/C). But, claiming all *_t and all _* as POSIX only is hubris.
The _* [for private functions] is quite common in other languages (e.g. python).
As to *_t types, I've been doing that for decades and never once hit a conflict. And, if I did, it's my responsibility as the programmer to fix that [by changing my code or the #include statements]. That is, assess the risks beforehand.
Worse, I also do (e.g.) typedef struct foo foo_t, *foo_p;. Note the *_p for a pointer type that seems to burn people here on SO.
But, it's arguably no worse that MS/Win's pType for pointers. And, it's my convention. And, it's passed code reviews plenty of times.
So, as Nixon once said (re. "Checkers"): Regardless of what they say about it, we're gonna keep it.
#ifndef MUST_REINVENT_THE_WHEEL
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char str[100];
printf("Write down a binary number. \n");
fgets(str,100,stdin);
printf("Decimal: %ld\n", strtol(str,0,2));
}
#endif
You want to accept an integer value that is the sum of 10^x
Eg 10^6 + 10^4 + 10^2 + 10^1 = 1010110 (base 10)
Then interpret that as a series binary bits
2^6 + 2^4 + 2^2 + 2^1 = 1010110 (base 2)
You're on the right path with dividing by ten, but I get lost in the confusing code that you've written. Here's a simple sample that seems to work (using long with my 32 bit compiler.) It combines bit-shifting and divide-by-ten, and testing whether-or-not to set the current bit in the output accumulator.
int main() {
long in = 10110101, wrk = in;
unsigned long out = 0;
for( unsigned long bit = 1; wrk; wrk /= 10, bit <<= 1 )
if( wrk & 1 )
out |= bit;
printf( "in %ld out %ld (hex %X )\n", in, out, out );
return 0;
}
in 10110101 out 181 (hex B5 )
Testing for negative values seems silly in this "toy" application. There's no way the range of 2^32 can accommodate 10^32.
Turned out my program was pretty much correct. Only thing I missed is the second if in the decimal function should be an else if.
Here's the correct program:
#include <stdio.h>
long long int decimal(long long int);
int power_2 (int);
int main(void){
long long int n;
while(1){
printf("Write down a binary number. \n");
scanf("%lld", &n);
long long int a = decimal(n);
printf("The binary number %lld converted into decimal is: %lld \n", n, a);
}
}
long long int decimal(long long int e){
long long int k = 0;
int i;
for(i=0; i>=0; i++){
if(e % 10 == 1){
k += power_2(i);
e--;
if(e != 0){
e /= 10;
}
}
else if(e % 10 == 0){
e /= 10;
}
if(e==0){
break;
}
}
return(k);
}
int power_2(int n){
int base = 2, i, result = 1;
if(n>0){
for(i=1; i<=n; i++){
result *= base;
}
}
if(n=0){
result = 1;
}
return(result);
}
Example:
Write down a binary number.
100010101011
The binary number 100010101011 converted into decimal is: 2219
I've written this code for converting Decimal numbers to binary but it prints the number vice versa how can I make this work?
Can I use getch command to make it happen we are currently learning getch.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
for(;n>0;n=n/2){
int d = n%2;
printf("%d", d);
}
return 0;
}
You can get tricky with this by using a recursive function:
#include <stdio.h>
void print_binary(int n)
{
if (n != 0) {
print_binary(n/2);
printf("%d ", n%2);
}
}
int main() {
int n;
scanf("%d", &n);
print_binary(n);
return 0;
}
By printing after the recursive call returns, the digits print in the reverse order.
Each time print_binary is called, it calls itself with an argument of n/2, then prints the least significant bit. However, each recursive call does the same thing.
Here's what the call stack looks like with n equal to 11 (binary 1011):
main
scanf
print_binary(11)
print_binary(5)
print_binary(2)
print_binary(1)
print_binary(0)
printf("%d ", 1);
printf("%d ", 0);
printf("%d ", 1);
printf("%d ", 1);
You can see that this results in the most significant bit being printed first.
Here is another way, working from most significant bit, with "zero supression". No reversal is needed.
#include <stdio.h>
int main(void) {
int n = 0; // the value
int hadone = 0; // 0 suppression control
int bits = 8 * sizeof n; // assume 8 bits for example
unsigned mask = 1u << (bits-1); // set msb of mask
scanf("%d", &n);
while(mask) {
if(n & mask) { // is it a 1 bit?
putchar('1');
hadone = 1; // cancel 0 suppression
}
else if(hadone || mask == 1) { // ensure a lone `0` goes out
putchar('0');
}
mask >>= 1; // next bit
}
putchar('\n');
return 0;
}
Program session:
42
101010
You can store digits into an array , and reverse it , to get the correct number .
Here's a non-recursive solution:
#include <stdio.h>
int main() {
int n;
char buf[100];
char *bp;
printf("Enter number: ");
fflush(stdout);
scanf("%d", &n);
bp = buf;
// store into array instead of printing [chars will be reversed]
// NOTE: we use "bp == buf" to force output if entered number is zero
for (; n>0 || bp == buf; n=n/2){
int d = n%2;
bp += sprintf(bp, "%d", d);
}
// print array in reverse order
for (bp -= 1; bp >= buf; --bp)
fputc(*bp,stdout);
printf("\n");
return 0;
}
I'm trying to create multiple functions using the same user input, I'm starting with decimal so I have an input function and the output
Next I'm going to do hexadecimal/ 8 bit binary and so on but I think I have the syntax wrong. I'm confused, I thought that you called the user input from main but I don't think that's correct.
Is there any advice anyone has that can help ? It says the variables are conflicting
#include <stdio.h>
int main (void)
{
int x;
scanf("%d", &x);
in_decimal();
out_decimal(x);
}
int in_decimal(void) {
printf(" Please type in a decimal:");
}
void out_decimal(int x;){
printf("%d",&x);
}
Try this uncompleted code:
#include <stdio.h>
#include <ctype.h>
unsigned int in_decimal();
void out_decimal(unsigned int x);
int main (void)
{
unsigned int x;
x = in_decimal();
out_decimal(x);
}
unsigned int in_decimal()
{
printf("Please type in a decimal: ");
int ch;
unsigned int x = 0;
do
{
ch = getchar();
if( ch < '0' || ch > '1')
{
break;
}
else
{
x *= 2;
x += ch - '0';
}
}
while( ch != '\n');
return x;
}
void out_decimal(unsigned int x){
if(x > 0)
{
out_decimal(x/2);
}
putchar('0' + x%2);
}
Now out_decimal() is recursive function and always output 0 at the beginning of numbers that are greater than zero. Think what you can change :-)
my binary conversion doesn't work after it recurs a second time, it seems to work only during the first time through. The purpose of the is have a user input a number to convert to Hex, Octal, and brinary from a integer and keep on asking and converting until the user inputs 0. Please help!
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
long toBinary(int);
int main(void) {
int number = 0;
long bnum;
int zero = 0;
while(number != zero) {
puts("\nPlease enter a number you would like to convert to");
puts("\nHexadecimal, octal, and binary: ");
scanf("%d", &number);
if(number != zero) {
printf("\nThe Hexadecimal format is: %x", number);
printf("\nThe Octal format is: %o", number);
bnum = toBinary(number);
printf("\nThe binary format is: %ld\n", bnum);
}
else {
puts("\nI'm sorry you have to enter a number greater than 0.\n");
puts("\nOr have enter an invalid entry.");
}
}
return 0;
}
long toBinary(int number) {
static long bnum, remainder, factor = 1;
int long two = 2;
int ten = 10;
if(number != 0) {
remainder = number % two;
bnum = bnum + remainder * factor;
factor = factor * ten;
toBinary(number / 2);
}
return bnum;
}
You just need a function to convert an integer to its binary representation.
Assuming the int is 32 bits then this should work:
#include <stdio.h>
int main()
{
char str[33];
str[32] = 0;
int x = 13, loop;
for (loop = 31; loop >= 0; --loop) {
str[loop] = (x & 1) ? '1' : '0';
x = x >> 1;
}
printf("As %s\n", str);
return 0;
}
You can make this into a function, read x etc...
EDIT
For octal/hex - printf will do this for you
EDIT
Here goes recursively
#include <stdio.h>
void PrintBinary(int n, int x) {
if (n > 0) {
PrintBinary(n - 1, x >> 1);
}
printf("%c",(x & 1) ? '1' : '0');
}
int main()
{
PrintBinary(32,12);
return 0;
}
First of all I am surprised it even works once. Firstly, your while condition is while number does not equal zero. But right off the bat, number equals 0 and zero equals 0. Therefore the while should never run. If you want to keep this condition for the main loop, change it to a do-while loop: do { //code } while (number != zero);. This will run the code at least once, then check if the inputted number doesn't equal zero. That brings me to the next issue; your scanf for number is scanning for a double and placing it in a regular integer memory spot. Quick fix: scanf("%i",&number);. Also I am finding some functions called puts.. I find it best to keep with one printing function, printf. Now, I am finding afew errors in your toBinary function, but if it works than I guess it works. These are all the errors i could find, I hope this helped. But for future reference there is no need to declare a variable for a const number like 2 or 10 at this level.
#include <stdint.h>
char* toBinary(int32_t number, int index){
static char bin[32+1] = {0}, *ret;
if(index == 32){
memset(bin, '0', 32);
return toBinary(number, 31);
} else if(number & (1<<index))
bin[31-index] = '1';
if(index)
(void)toBinary(number, index-1);
else
for(ret = bin; *ret == '0';++ret);
return ret;
}
...
int number = -1;
...
printf("\nThe binary format is: %s\n", toBinary(number, 32));
Consider the following simple C program.
//C test
#include<stdio.h>
int main()
{
int a, b, c;
printf("Enter two numbers to add\n");
scanf("%d%d",&a,&b);
c = a + b;
printf("Sum of entered numbers = %d\n",c);
return 0;
}
How do you check the values entered are actually two integers in some sensible range? Currently, if you just enter "a" and then return you get the output "Sum of entered numbers = 32767".
Examples of incorrect input I would like to prevent.
2 3 4 (wrong number of numbers)
apple (not a number)
11111111111111111111111111 1111111111111111111111111111111111111 (numbers out of range)
Or should I be using fgets and sscanf or even strtol ?
User input is evil. Parse per:
(optional whitespace)[decimal int][whitespace][decimal int](optional whitespace)
strtol() and family have better error handling than scanf().
Coda: Best to handle user input in a helper function. Break into 2 parts: I/O and parsing.
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
// return 1 (success), -1 (EOF/IOError) or 0 (conversion failure)
int Readint(const char *prompt, int *dest, size_t n) {
char buf[n * 21 * 2]; // big enough for `n` 64-bit int and then 2x
fputs(prompt, stdout); // do not use printf here to avoid UB
fflush(stdout); // per #OP suggestion
if (fgets(buf, sizeof buf, stdin) == NULL) {
return -1;
}
const char *p = buf;
while (n-- > 0) {
char *endptr;
errno = 0;
long l = strtol(p, &endptr, 10);
if (errno || (p == endptr) || (l < INT_MIN) || (l > INT_MAX)) {
return 0;
}
*dest++ = (int) l;
p = endptr;
}
// Trailing whitespace OK
while (isspace((unsigned char) *p)) p++;
// Still more text
if (*p) return 0;
return 1;
}
int main() { // for testing
int Result;
do {
int dest[2] = { -1 };
Result = Readint("Enter two numbers to add\n", dest, 2);
printf("%d %d %d\n", Result, dest[0], dest[1]);
} while (Result >= 0);
return 0;
}
You can use like:
if( scanf("%d%d",&a,&b) == 2)
{
//two integer values has been read successfully
//do your stuff here
}
else
{
//Wrong input
}
Also you can do this to prevent anything after second number
int a,b;
char c;
if( scanf("%d%d%c", &a, &b, &c) == 3) {
if (c == '\n') {
puts("good");
}
} else {
puts("bad");
}
return 0;
}
You can use the following macro
#define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \
do {\
char tmp;\
while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\
|| !(COND)) {\
printf("Invalid input, please enter again: ");\
}\
} while(0)
and you call it in this way in the main
int main()
{
int a, b, c;
printf("Input first integer, valid choice between 0 and 10: ");
SCAN_ONEENTRY_WITHCHECK("%d",&a,(a>=0 && a<=10));
printf("Input second integer, valid choice between 0 and 10: ");
SCAN_ONEENTRY_WITHCHECK("%d",&b,(b>=0 && b<=10));
c = a + b;
printf("Sum of entered numbers = %d\n",c);
return 0;
}
for more detail concerning this macro please refer to: Common macro to read input data and check its validity
A simple way would be,
int a=0, b=0, c=0;
initialise them to 0
Additionally, the check suggested by Midhun is good to check if there are two inputs.
you can test this one.
#include <stdio.h>
int main(void)
{
int a, b, c;
printf("Enter two numbers to add\n");
scanf("%d%d",&a,&b);
if(scanf("%d%d",&a,&b) == 2)
{
c = a + b;
printf("Sum of entered numbers = %d\n",c);
}
return 0;
}