Calculating sum of certain previously inputted numbers - c

This program should calculate the sum of all numbers whose digits are in descending order. It stops you from inputting if the number isn't a whole number. I think that the problem might be because of the sum variable, but I don't know how to fix it.
Edit: Per #user3386109 request, here is the output I get:
4321
75
56
4,79
0
The sum should be 4396, as sum of 4321 and 75. Not 0.
Sorry for the unclear question I am quite new to this.
int n, last, secondlast, sum, c = 0;
int temp;
while (scanf("%d", &n) == 1) {
sum = 0;
while (temp > 0) {
last = temp % 10;
secondlast = (temp / 10) % 10;
if (secondlast > last) {
c++;
sum = sum + temp;
}
temp = temp / 10;
}
}
if (c == 0) {
printf("There are no numbers that meet the requirements\n");
}
else {
printf("%d\n", sum);
}

As #Support Ukraine commented, this code gets the job done.
#include <stdio.h>
int descendingDigits(int n)
{
int current = n % 10;
n = n / 10;
while(n)
{
int this = n % 10;
if (this <= current) return 0;
current = this;
n = n / 10;
}
return 1;
}
int main(void) {
int sum = 0;
int c = 0;
int n = 0;
while (scanf("%d", &n) == 1) {
if (descendingDigits(n))
{
sum = sum + n;
c = 1;
}
}
if (c == 0) {
printf("There are no numbers that meet the requirements\n");
}
else
{
printf("%d\n", sum);
}
return 0;
}

%10 operations are really not the best way to determine if the digits are descending. It works, but it seems like overkill to use scanf to convert the input to an integer at all, since it's much easier to know if the digits are in order if you leave them as a string. It's tempting to check if the digits of the string are descending and only convert to an integer value if they are, but it seems like a bad idea to parse the string twice. In other words; read the input as a string and do not convert, then compute the integer value while you are looking at the digits to see if they are descending. This is aesthetically appealing, since you minimize computations. (eg, if the input string is "47901", you shouldn't waste cpu cycles converting that to the integer 47901; after you see that 7 is not less than 4, you can abort).
eg:
#include <ctype.h>
#include <stdio.h>
/* If the string s represents an integer
* with (strictly) descending digits, return
* its integer representation (base 10). Else
* return 0.
*/
unsigned
is_descending(const char *s)
{
unsigned rv = 0;
int last = '9' + 1;
while( *s ){
if( isdigit(*s) && *s < last ){
rv = 10 * rv + *s - '0';
} else {
return 0;
}
last = *s++;
}
return rv;
}
int
main(int argc, char **argv)
{
char buf[64];
unsigned sum = 0;
while( scanf("%63s", buf) == 1 ){
sum += is_descending(buf);
}
printf("sum: %u\n", sum);
return 0;
}
Note that this does not handle negative numbers well, but it's not clear how you want to deal with that. Left as an exercise for the reader.

Related

How can print string num?

Problem:
How can print string num? It seems that final statement cannot execute?
Question desciptions:
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!
Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.
/* Have Fun with Numbers */
#include <stdio.h>
#include <string.h>
int book[10] = { 0 };
int main(int argc, char* argv[])
{
char num[22];
int temp = 0;
scanf_s("%s", num, 1);
// Length of numbers
int len = strlen(num);
int flag = 0;
for (int i = len - 1; i >= 0; --i) {
// Convert an ASCII value of a digit into an integer
temp = num[i] - '0';
// Add 1 each time read a digit
++book[temp];
temp = temp * 2 + flag;
flag = 0;
if (temp >= 10) {
temp -= 10;
flag = 1;
}
// Convert an integer into an ASCII value of a digit
num[i] = (temp + '0');
// Subtract 1 each time generate a digit
--book[temp];
}
int flag1 = 0;
for (int i = 0; i < 10; ++i) {
if (book[i] != 0) {
flag1 = 1;
}
}
printf("%s", (flag == 1 || flag1 == 1) ? "No\n" : "Yes\n");
if (flag == 1) {
printf("1");
}
printf("%s", num);
return 0;
}
In this like
scanf_s("%s", num, 1);
You are reporting the buffer size as 1 to scanf_s() while the actual size is 22.
Use correct buffer size.
scanf_s("%s", num, 22);
or
scanf_s("%s", num, (unsigned)(sizeof(num) / sizeof(*num)));

Segmentation fault in base number program?

I keep trying to test this code but I keep getting a segmentation fault in my power() function. The code is supposed to take a word made up of lowercase letters and change the word to a number of base 10. The word is supposed to take on the form of a number of base 20, where 'a' = 0, 'b' = 1,...., 't' = 19;
int power(int i){
if(i==1){
return 20;
}else{
return 20*power(i--);
}
}
int main(){
int len;
char mayan[6];
int n;
int val;
while(scanf("%s", mayan)){
val = 0;
n = 0;
for(len = 0; mayan[len] != '\0'; len++){
mayan[len] = tolower(mayan[len]);
mayan[len] = mayan[len] - 'a';
}
for(i = 0; len >= 0; len--, i++){
if(mayan[len] <= 19){
n = n + mayan[len] * power(i);
}else{
fprintf(stderr, "Error, not a base 20 input \n");
val = 1;
break;
}
}
if(val==0){
printf("%d \n", n);
}
}
return val;
}
There were three mistakes in your code.
Case for i==0 not added in the power function, which basically translates to any number to the power of zero is one i.e. x^0 = 1;.
Instead of using return 20*power(i--); for your recursive call, use return 20*power(i-1);. i-- is post decrement operator, which means that, it will return the value of i as it is and will the decrement it for further use, which is not what you want. Also, you altogether don't even want to change the value of i for this iteration too; what you want to do is use a value one less than i for the next iteration, which is what, passing i-1, will do.
Add a len-- in the initialization of the for(i = 0; len >= 0; len--, i++) loop, because len is now over the last index of the input because of the previous loop.
Correcting these mistakes the final code is:
#include<stdio.h>
int power(int i)
{
if(i==0)
{
return 1;
}
if(i==1)
{
return 20;
}
else
{
return 20*power(i-1);
}
}
int main()
{
int len,i;
char mayan[6];
int n;
int val;
while(scanf("%s", mayan))
{
val = 0;
n = 0;
for(len = 0; mayan[len] != '\0'; len++)
{
mayan[len] = tolower(mayan[len]);
mayan[len] = mayan[len] - 'a';
}
for(i = 0, len--; len >= 0; len--, i++)
{
if(mayan[len] <= 19)
{
n = n + mayan[len] * power(i);
}
else
{
fprintf(stderr, "Error, not a base 20 input \n");
val = 1;
break;
}
}
if(val==0)
{
printf("%d \n", n);
}
}
return val;
}
Note that, your code would essentially only work for at most a five digit base 20 number, because, the array mayan that you are using to store it has size 6, of which, one character will be spent for storing the terminating character \0. I recommend that you increase the size of the array mayan unless you want to support only five digit base 20 numbers.

Convert decimal to binary in C

I am trying to convert a decimal to binary such as 192 to 11000000. I just need some simple code to do this but the code I have so far doesn't work:
void dectobin(int value, char* output)
{
int i;
output[5] = '\0';
for (i = 4; i >= 0; --i, value >>= 1)
{
output[i] = (value & 1) + '0';
}
}
Any help would be much appreciated!
The value is not decimal. All values in computer's memory are binary.
What you are trying to do is to convert int to a string using specific base.
There's a function for that, it's called itoa.
http://www.cplusplus.com/reference/cstdlib/itoa/
First of all 192cannot be represented in 4 bits
192 = 1100 0000 which required minimum 8 bits.
Here is a simple C program to convert Decimal number system to Binary number system
#include <stdio.h>
#include <string.h>
int main()
{
long decimal, tempDecimal;
char binary[65];
int index = 0;
/*
* Reads decimal number from user
*/
printf("Enter any decimal value : ");
scanf("%ld", &decimal);
/* Copies decimal value to temp variable */
tempDecimal = decimal;
while(tempDecimal!=0)
{
/* Finds decimal%2 and adds to the binary value */
binary[index] = (tempDecimal % 2) + '0';
tempDecimal /= 2;
index++;
}
binary[index] = '\0';
/* Reverse the binary value found */
strrev(binary);
printf("\nDecimal value = %ld\n", decimal);
printf("Binary value of decimal = %s", binary);
return 0;
}
5 digits are not enough for your example (192). Probably you should increase output
A few days ago, I was searching for fast and portable way of doing sprintf("%d", num). Found this implementation at the page itoa with GCC:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
It looks like this, but be careful, you have to reverse the resulting string :-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char output[256]="";
int main()
{
int x= 192;
int n;
n = x;
int r;
do {
r = n % 2;
if (r == 1)
strcat(output,"1");
else strcat(output,"0");
n = n / 2;
}
while (n > 0);
printf("%s\n",output);
}
So... did you check the output of your code to understand why it doesn't work?
So iteration 1 of your loop:
value = 192
i = 4
output[i] = (11000000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 2 of your loop:
value = 96
i = 3
output[i] = (1100000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 3 of your loop:
value = 48
i = 2
output[i] = (110000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 4 of your loop:
value = 24
i = 1
output[i] = (11000 & 1) + '0' = 0 + 48 = 48 (char `0`)
Iteration 5 of your loop:
value = 12
i = 0
output[i] = (1100 & 1) + '0' = 0 + 48 = 48 (char `0`)
Final string: "00000" and you wanted: "11000000"
See anything wrong with your code? Nope. Neither do I you just didn't go far enough. Change your output/loop to:
output[8] = '\0';
for (i = 7; i >= 0; --i, value >>= 1)
And then you'll have the correct result returned.
I would recomend just a more general approach, you're using a fixed length string, which limits you to binary numbers of a certian length. You might want to do something like:
loop while number dividing down is > 0
count number of times we loop
malloc an array the correct length and be returned
#include <stdio.h>
#include <stdlib.h>
void bin(int num) {
int n = num;
char *s = malloc(sizeof(int) * 8);
int i, c = 0;
printf("%d\n", num);
for (i = sizeof(int) * 8 - 1; i >= 0; i--) {
n = num >> i;
*(s + c) = (n & 1) ? '1' : '0';
c++;
}
*(s + c) = NULL;
printf("%s", s); // or you can also return the string s and then free it whenever needed
}
int main(int argc, char *argv[]) {
bin(atoi(argv[1]));
return EXIT_SUCCESS;
}
You can do it using while loop under a function also. I was just searching the solve for mine but the solves i get were not suitable, so I have done it accordingly the practical approach (divide using 2 until getting 0 and store the reminder in an array) and print the reverse of the array and Shared Here
#include <stdio.h>
int main()
{
long long int a,c;
int i=0,count=0;
char bol[10000];
scanf("%lld", &a);
c = a;
while(a!=0)
{
bol[i] = a%2;
a = a / 2;
count++;
i++;
}
if(c==0)
{
printf("0");
}
else
{
for(i=count-1; i>=0; i--)
{
printf("%d", bol[i]);
}
}
printf("\n");
return 0;
}
//C Program to convert Decimal to binary using Stack
#include<stdio.h>
#define max 100
int stack[max],top=-1,i,x;
void push (int x)
{
++top;
stack [top] = x;
}
int pop ()
{
return stack[top];
}
void main()
{
int num, total = 0,item;
print f( "Please enter a decimal: ");
scanf("%d",&num);
while(num > 0)
{
total = num % 2;
push(total);
num /= 2;
}
for(i=top;top>-1;top--)
{
item = pop ();
print f("%d",item);
}
}
Convert Decimal to Binary in C Language
#include<stdio.h>
void main()
{
long int n,n1,m=1,rem,ans=0;
printf("\nEnter Your Decimal No (between 0 to 1023) :: ");
scanf("%ld",&n);
n1=n;
while(n>0)
{
rem=n%2;
ans=(rem*m)+ans;
n=n/2;
m=m*10;
}
printf("\nYour Decimal No is :: %ld",n1);
printf("\nConvert into Binary No is :: %ld",ans);
}
This is the simplest way to do it
#include <stdio.h>
void main()
{
int n,i,j,sum=0;
printf("Enter a Decimal number to convert it to binary : ");
scanf("%d",&n);
for(i=n,j=1;i>=1;j*=10,i/=2)
sum+=(i%2)*j;
printf("\n%d",sum);
}
This is a simple program to convert a number from decimal to binary
#include <stdio.h>
#include <conio.h>
void decToBinary(int);
int main()
{
int number;
printf("Enter number to convert to binary: ");
scanf("%d", &number);
decToBinary(number);
return 0;
}
void decToBinary(int num)
{
if (num == 0)
{
return ;
}
decToBinary(num / 2);
printf("%d", num % 2);
}
Output of the Program:
Perhaps understanding the algorithm would allow you write or modify your own code to suit what you need. I do see that you don't have enough char array length to display your binary value for 192 though (You need 8 digits of binary, but your code only gives 5 binary digits)
Here's a page that clearly explains the algorithm.
I'm not a C/C++ programmer so here's my C# code contribution based on the algorithm example.
int I = 0;
int Q = 95;
string B = "";
while (Q != 0)
{
Debug.Print(I.ToString());
B += (Q%2);
Q = Q/2;
Debug.Print(Q.ToString());
I++;
}
Debug.Print(B);
All the Debug.Print is just to show the output.
//decimal to binary converter
long int dec2bin(unsigned int decimal_number){
if (decimal_number == 0)
return 0;
else
return ((decimal_number%2) + 10 * dec2bin(decimal_number/2));
}
number=215
a=str(int(number//128>=1))+str(int(number%128>=64))+
str(int(((number%128)%64)>=32))+str(int((((number%12
8)%64)%32)>=16))+str(int(((((number%128)%64)%32)%16)>=8))
+str(int(((((((number%128)%64)%32)%16)%8)>=4)))
+str(int(((((((((number%128)%64)%32)%16)%8)%4)>=2))))
+str(int(((((((((((number%128)%64)%32)%16)%8)%4)%2)>=1)))))
print(a)
You can also use the 'if', 'else', statements to write this code.
int main()
{
int n, c, k;
printf("Enter an integer in decimal number system: ");
scanf("%d", &n);
printf("%d in binary number system is: ", n);
for (c = n; c > 0; c = c/2)
{
k = c % 2;//To
k = (k > 0) ? printf("1") : printf("0");
}
getch();
return 0;
}

Print an int in C without Printf or any functions

I have an assignment where I need to print an integer in C without using printf, putchar, etc. No header files allowed to be included. No function calls except for anything I wrote. I have one function my_char I am using (maybe its wrong) but it prints out a character. I currently have the following code which is printing the number out backwards. Not looking for an answer. Just looking for some direction, some help, maybe I'm looking at it completely wrong.
void my_int(int num)
{
unsigned int i;
unsigned int j;
char c;
if (num < 0)
{
my_char('-');
num = -num;
}
do
{
j = num % 10;
c = j + '0';
my_char(c);
num = num/10;
}while(num >0);
}
Instead of calling my_char() in the loop instead "print" the chars to a buffer and then loop through the buffer in reverse to print it out.
Turns out you can't use arrays. In which case you can figure out the max power of 10 (ie log10) with the loop. Then use this to work backwards from the first digit.
unsigned int findMaxPowOf10(unsigned int num) {
unsigned int rval = 1;
while(num) {
rval *= 10;
num /= 10;
}
return rval;
}
unsigned int pow10 = findMaxPowOf10(num);
while(pow10) {
unsigned int digit = num / pow10;
my_char(digit + '0');
num -= digit * pow10;
pow10 /= 10;
}
One option might be to do this recursively, so the number gets printed out in the right order.
In this case, instead of a do/while loop, you'd have a construction more like this, with a base case of num=0.
if(num==0)
return;
j = num % 10;
c = j + '0';
my_int(num/10);
my_char(c);
Edit: Noticed that you aren't allowed to use recursion. It's a bit ugly, but you could check for the digits in the number, and then loop backwards across the number.
To find the number of digits,
int digitDivide = 1;
int tempNum = num;
while(tempNum>0){
tempNum= tempNum/10;
digitDivide=digitDivide*10;
}
and then use that to loop through the number as follows:
digitDivide = digitDivide/10;
while(digitDivide>0){
tempNum = (num/digitDivide)%10;
c = j + '0';
my_char(c);
digitDivide=digitDivide/10;
}
You can convert an int to char * , char * and display this char* :
char *put_int(int nb)
{
char *str;
str = malloc(sizeof(char) * 4);
if (str == NULL)
return (0);
str[0] = (nb / 100) + '0';
str[1] = ((nb - ((nb / 100 * 100 )) / 10) + '0');
str[2] = ((nb % 10) + '0');
return (str);
}
void put_str(char *str)
{
while (*str)
write(1, str++,1);
}
int main(void)
{
put_str(put_int(42));
return (0);
}

Convert binary format string to int, in C

How do I convert a binary string like "010011101" to an int, and how do I convert an int, like 5, to a string "101" in C?
The strtol function in the standard library takes a "base" parameter, which in this case would be 2.
int fromBinary(const char *s) {
return (int) strtol(s, NULL, 2);
}
(first C code I've written in about 8 years :-)
If it is a homework problem they probably want you to implement strtol, you would have a loop something like this:
char* start = &binaryCharArray[0];
int total = 0;
while (*start)
{
total *= 2;
if (*start++ == '1') total += 1;
}
If you wanted to get fancy you could use these in the loop:
total <<= 1;
if (*start++ == '1') total^=1;
I guess it really depends on some questions about your strings/program. If, for example, you knew your number wouldn't be bigger than 255 (IE you were only using 8 bits or 8 0s/1s), you could create a function where you hand it 8 bits from your string, traverse it and add to a sum that you returned everytime you hit a 1. IE if you hit the bit for 2^7 add 128 and the next bit you hit was 2^4 add 16.
This is my quick and dirty idea. I think more and Google for ya while at school. :D
For the 2nd part of the question, i.e. "how do I convert an int, like 5, to a string "101" in C?", try something like:
void
ltostr( unsigned long x, char * s, size_t n )
{
assert( s );
assert( n > 0 );
memset( s, 0, n );
int pos = n - 2;
while( x && (pos >= 0) )
{
s[ pos-- ] = (x & 0x1) ? '1' : '0'; // Check LSb of x
x >>= 1;
}
}
You can use the following coding
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
int nRC = 0;
int nCurVal = 1;
int sum = 0;
char inputArray[9];
memset(inputArray,0,9);
scanf("%s", inputArray);
// now walk the array:
int nPos = strlen(inputArray)-1;
while(nPos >= 0)
{
if( inputArray[nPos] == '1')
{
sum += nCurVal;
}
--nPos;
nCurVal *= 2;
}
printf( "%s converted to decimal is %d\n", inputArray, sum);
return nRC;
}
Use like this:
char c[20];
int s=23;
itoa(s,c,2);
puts(c);
Output:
10111
To answer the second part of the question.
char* get_binary_string(uint16_t data, unsigned char sixteen_bit)
{
char* ret = NULL;
if(sixteen_bit) ret = (char*)malloc(sizeof(char) * 17);
else ret = (char*)malloc(sizeof(char) * 9);
if(ret == NULL) return NULL;
if(sixteen_bit){
for(int8_t i = 15; i >= 0; i--){
*(ret + i) = (char)((data & 1) + '0');
data >>= 1;
}
*(ret + 16) = '\0';
return ret;
}else{
for(int8_t i = 7; i >= 0; i--){
*(ret + i) = (char)((data & 1) + '0');
data >>= 1;
}
*(ret + 8) = '\0';
return ret;
}
return ret;
}
To answer the first part of your question, here is a neat little function I created to convert Binary char strings to integers.
// Function used to change binary character strings to integers
int binToDec(char binCode[])
{
while (binCode != NULL)
{
int base = strlen(binCode) - 1; // the base of 2 to be multiplied, we start of -1 because we dont account for the last bit here
int sum = 0;
for (int i = 0; i < strlen(binCode) - 1; i++) // we do not account for the last bit of the binary code here....
{
int decimal = 1;
if (binCode[i] == '1')
{
for (int j = 0; j < base; j++) // we want to just multiply the number of true bits (not including the 1)
{
decimal = decimal * 2;
}
base = base - 1; // subtract base by 1 since we are moving down the string by 1
}
else // we encounter a zero
{
base = base - 1; // subtract a base multiple every time we encounter a zero...
continue; // carry on with the code
}
sum += decimal;
// starting from the left (higher power) to the end (lowest power or 1)
}
for (int j = strlen(binCode) - 1; j < strlen(binCode) + 1; j++)
{ // accounting for the endian bit that is always 1
if (binCode[j] == '1')
{
sum += 1; // add 1 to the sum total
}
}
return sum; // return the sum as an int
}
return 0;
}

Resources