I want to print a breakdown of an integer, only outputting non-zero numbers. For example: ./printint 23401 will print: 20000 + 3000 + 400 + 1 Note: the tens value of 0 is omitted.
That is my code so far:
#include <stdio.h>
int main(int argc, const char * argv[]) {
int n = 23401;
int g,s,b,q,w;
g=n%10;
s=(n/10)%10*10;
b=(n/100)%10*100;
q= (n/1000)%10*1000;
w= n/10000*10000;
printf("%d" ,"+","%d","+","%d","+","%d","+","%d\n",w,q,b,s,g);
return 0;
}
I am new at coding and new at C. I am also trying to get input but it is hard to think it thoroughly, so I am just using the example in the question. Also, I have a problem with the connect style in the printf().
As with any problem, you simply need to break the complex problem down into smaller problems that you can solve, code a solution for each of the parts and then consolidate all of the individual coded solutions into your final code. In this case that can be thought of as:
prompt user for input,
read and VALIDATE the user input,
handle the corner-case of the user entering 0 which has no additive component,
determine if the number entered was negative, make positive and save flag indicating original was negative,
determine the number of digits in the number entered by the user,
generate a power of 10 for that many digits,
loop over the number dividing by the power of 10, output the resulting power of 10 formed by digit * power of 10 (if non-zero), and reduce the number by that amount and divide your power of 10 by 10 and repeat until your power of 10 is zero.
Now just go write the code for the pieces. Let's decide on a few variable names that we will need before coding up each step (to server as a guide-post as we work through the steps). On a 64-bit computer with a 8-byte long, choosing long as the type to hold your number entered by the user makes sense for handling negative values. We will add a few more to help with the rest of the code. Five variables should do it, e.g.
#include <stdio.h>
int main (void) {
int ndigits, sign = 0; /* number of digits, sign (1 if negative) */
long num /* the number to get from user */
unsigned long limit = 1, n; /* divisor limit, working var for num */
Let's start with Step 1. - prompting for input. There is no conversion required, and if we want the input to be at the end of the line instead of below it, fputs is a good choice for the prompt (use puts if you want to output a newline forcing the user input to the next line), e.g.
fputs ("enter number in range of long int: ", stdout);
Step 2. - read and VALIDATE the user-input (every user input) and handle the error if invalid input is provided (we simply return 1; from main() exiting if an invalid integer is entered):
if (scanf ("%ld", &num) != 1) { /* validate input */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
Step 3. - handle the case if the user enters 0 where there will be nothing to add to obtain your final number:
if (!num) { /* handle 0 corner-case */
printf ("%ld : ()\n", num);
return 0;
}
(we will also output the number entered by the user at this point and output the remainder in the loop and following the loop. call this Step 3a.)
printf ("%ld : ", num); /* output orignal number */
Step 4. determine if the number is negative, and if so, make it positive and save a flag indicating the original input was negative. (you could just output the '-' in this case and do away with the flag, but you won't always have that opportunity -- so get used to saving the state with a simple flag if required)
if (num < 0) { /* if negative set sign=1, make positive */
sign = 1;
num = -num;
}
n = num; /* set working variable for num */
(note: we also set our working variable n = num; at this point. If you don't want to preserve the original, you can dispense with using a working variable and just modify the original as needed -- as we could here since we have already output the original)
Step 5. - determine the number of digits in the number entered by the user:
ndigits = snprintf (NULL, 0, "%ld", num); /* get number of digits in num */
(yes: snprintf with a destination of NULL and length of 0 provides a very convenient way to calculate the number of characters that would be required to hold the number converted to a string)
Step 6. - generate a power of 10 for the number of digits entered:
for (int i = 1; i < ndigits; i++) /* set power of 10 limit */
limit *= 10;
(before entering our loop we check if the original number was negative an output the '-' at this point -- a step 6a.):
if (sign) /* if negative, output '-' */
putchar ('-');
Step 7. loop over the number dividing by the limit power of 10 and outputting the resulting component power of 10 (if non-zero) that you would add to arrive at the final number. We then reduce our working variable by that amount and divide the power of 10 (by 10) and repeat until the power of 10 is zero, you can do:
while (limit) { /* loop over each power of 10 */
int digit = n / limit; /* is there a digit at that power of 10? */
if (digit) { /* if so, output digit * power of 10 */
printf (n != (unsigned long)num ? " + %lu" : "(%lu", digit * limit);
}
n -= digit * limit; /* subtract digit * power of 10 */
limit /= 10; /* reduce limit by power of 10 */
}
All that remains is tidying up the output any way you like. We'll add a closing parenthesis just to make it look nice. And this is also were you would figure out where you wanted to put the remainder of your output during the program (what led to all the 3a. and 6a. steps, etc..)
puts (")"); /* output closing paren */
}
If you collect all the pieces and put them together you would have:
#include <stdio.h>
int main (void) {
int ndigits, sign = 0; /* number of digits, sign (1 if negative) */
long num /* the number to get from user */
unsigned long limit = 1, n; /* divisor limit, working var for num */
fputs ("enter number in range of long int: ", stdout);
if (scanf ("%ld", &num) != 1) { /* validate input */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
if (!num) { /* handle 0 corner-case */
printf ("%ld : ()\n", num);
return 0;
}
printf ("%ld : ", num); /* output orignal number */
if (num < 0) { /* if negative set sign=1, make positive */
sign = 1;
num = -num;
}
n = num; /* set working variable for num */
ndigits = snprintf (NULL, 0, "%ld", num); /* get number of digits in num */
for (int i = 1; i < ndigits; i++) /* set power of 10 limit */
limit *= 10;
if (sign) /* if negative, output '-' */
putchar ('-');
while (limit) { /* loop over each power of 10 */
int digit = n / limit; /* is there a digit at that power of 10? */
if (digit) { /* if so, output digit * power of 10 */
printf (n != (unsigned long)num ? " + %lu" : "(%lu", digit * limit);
}
n -= digit * limit; /* subtract digit * power of 10 */
limit /= 10; /* reduce limit by power of 10 */
}
puts (")"); /* output closing paren */
}
Example Use/Output
Now run it and make sure it does what you intend, and if not -- go fix it.
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: 23401
23401 : (20000 + 3000 + 400 + 1)
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: 20431
20431 : (20000 + 400 + 30 + 1)
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: 1
1 : (1)
Handle zero:
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: 0
0 : ()
Handle negative values:
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: -1
-1 : -(1)
$ ./bin/pwrsof10sum_scanf
enter number in range of long int: -29031
-29031 : -(20000 + 9000 + 30 + 1)
Note. instead of prompting the user for input with scanf, you can simply set a default value for num in your code and then provide any number you want to test as the first argument to your program. That avoids all the prompting and input during the testing phase. If you want to give it a try, just replace your scanf entry with a check to see if an argument was provided on the command line, and if so, convert and assign to num using sscanf instead, e.g.
#include <stdio.h>
int main (int argc, char **argv) {
int ndigits, sign = 0; /* number of digits, sign (1 if negative) */
long num = 23401; /* the number */
unsigned long limit = 1, n; /* divisor limit, working var for num */
/* check if new mumber provided on command line, convert to long */
if (argc > 1 && sscanf (argv[1], "%ld", &num) != 1) {
fputs ("error: invalid non-integer argument.\n", stderr);
return 1;
}
(the only change is the default value for num and then the check of argc and conversion and VALIDATION with sscanf.
Look things over and let me know if you have further questions.
Related
I am stuck in this problem, 2 integers A and B must be entered, and A must be separated into digits with respect to B, example: A:1234 B:2 You must separate 12, 23, 34, and then verify how many prime numbers are between these digits
This is what I was able to do so far, I would appreciate it if you could guide me to know which way to go
#include <stdio.h>
int main() {
int A, B, i, contador;
//Introducimos el Numero A y verificamos que sea mayor a 0
for (i = 0; i != -1; i++) {
printf("\nIngrese el numero A :");
scanf("%d", &A);
if (A > 0) {
break;
}
}
//Introducimos el Numero B y verificamos que sea mayor a 0
for (i = 0; i != -1; i++) {
printf("\nIngrese el numero B :");
scanf("%d", &B);
if (B > 0) {
break;
}
}
printf("A\t\tB\t\tCifras\t\tCantidad Primos\n");
printf("%d\t\t%d", A, B);
return 0;
}
First we can greatly simplify validating input with a while loop for each variable that will loop until it scans in a number successfully and it's greater than zero.
Second, we can convert that input number to a string with sprintf which makes looping over individual chunks easier.
Having isolated substrings representing chunks of digits, strtol can convert them back to ints. Below I have simply printed them, but you could readily store them in an array for further manipulation.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
int A = 0, B = 0;
while (scanf("%d", &A) != 1 || A <= 0);
while (scanf("%d", &B) != 1 || B <= 0);
char s[1024];
sprintf(s, "%d", A);
for (int i = 0; i < strlen(s) - B + 1; i++) {
char ss[B+1];
for (int j = 0; j < B; j++) {
ss[j] = s[i + j];
}
ss[B] = '\0';
int n = strtol(ss, NULL, 10);
printf("%d\n", n);
}
return 0;
}
There's no need for conversion to/from a string of digits.
You've got the "user input", so far.
The following skips that step, using 2 compile-time int's instead.
int main() {
int v1 = 1357924680, v2 = 3; // simulate two reasonable values from the user.
printf( "Using %d and %d as input\n", v1, v2 );
// calculate the power of 10 that has 'v2' zeros.
int divisor = 1;
while( v2-- ) divisor *= 10;
// from right-to-left, push 2-3-4-... digit values onto a stack
int stack[32] = { 0 }, spCnt = -1;
while( v1 > divisor/10 )
stack[ ++spCnt ] = v1 % divisor, v1 /= 10;
// retrieve (in order) pairs of values from the stack.
for( ; spCnt > 0; spCnt-- ) {
printf( "%d and %d\n", stack[ spCnt ], stack[ spCnt - 1 ] );
/* call your function that prints all the primes between these values. */
}
return 0;
}
Using 1234567890 and 2 as input
12 and 23
23 and 34
34 and 45
45 and 56
56 and 67
67 and 78
78 and 89
89 and 90
Using 1357924680 and 3 as input
135 and 357
357 and 579
579 and 792
792 and 924
924 and 246
246 and 468
468 and 680
There are a number of ways you can approach parsing the input of digits into groups of digits to be checked as prime. A very straight-forward approach is to read the digits into a C-string and then convert the groups of digits desired into integer values. That process can also be done a number of different ways. One instructive way is simply to manually handle grouping the number of desired digits to check and manually converting each group of digits to an integer value to check if prime.
Whenever you are reading input from the user, you are encourage to read a line of input at-a-time to avoid the pitfalls inherent in a formatted-read using scanf() (matching-failures and characters left unread in stdin just waiting to bite you on your next input --> which is the reason for the infinite-loop discussed below your other answer) Reading input with fgets() into a sufficiently sized buffer (character array) ensures are characters are read and nothing remains unread in stdin.
So long as you are not on an embedded system or microcontroller, C provides the constant BUFSIZ which you can use to size your character array, that is sufficient for most inputs you will encounter. In your case two arrays are needed, a separate buffer to hold the digits you will group and convert, and a second general buffer to take the other (B) input with. You can declare your buffers and read the digits with something similar to the following:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXDIGITS BUFSIZ
...
int main (void) {
char buf[MAXDIGITS], /* general input buffer */
digits[MAXDIGITS]; /* buffer to hold digits */
int ndigits = 0; /* digits to separate and test */
/* read/validate input A */
fputs ("enter number : ", stdout);
if (!fgets (digits, sizeof digits, stdin)) {
puts ("(user canceled input)");
return 0;
}
digits[strcspn (digits, "\n")] = 0; /* trim trailing '\n' */
...
(note: fgets() reads and includes the '\n' generated by the user pressing Enter. A simple way to remove it is to overwrite the '\n' character with 0 -- the nul-terminating character. strcspn() provides an efficient manner for doing so as shown above)
Since you are reading digits, you will want to check that the input is comprised of all digits. You can write a simple function to check if each character entered isdigit() with the function (or macro) provided in ctype.h, e.g.
/* simple function checks if s is composed of all digits,
* returns 1 if so, 0 otherwise.
*/
int all_digits (const char *s)
{
int i = 0;
if (!*s || *s == '\n') { /* check empty-string or empty-line */
return 0;
}
for (; s[i]; i++) { /* loop over each digit */
if (!isdigit((unsigned char)s[i])) {
break;
}
}
return !s[i]; /* end-of-string */
}
If the user input into digits is all-digits, you can proceed to take the second input of the number of digits to group together to check for prime. The approach is the same, read with fgets() into buf and then convert the number to int and validate the number represents a group-size that is possible given the number of digits in digits, e.g.
if (!all_digits (digits)) { /* validate input all digits */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
/* read / validate input B */
fputs ("combine ndigits : ", stdout);
if (!fgets (buf, sizeof buf, stdin)) {
puts ("(user canceled input)");
return 0;
}
/* convert string to int / validate */
if (sscanf (buf, "%d", &ndigits) != 1) {
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
/* validate the number of digits to combine is possible */
if (ndigits <= 0 || (size_t)ndigits > strlen (digits)) {
fputs ("error: requested combination of digits not possible.\n",
stderr);
return 1;
}
With both inputs taken and the number of digits ndigits to group validated, you can convert your groups to int and check for prime. A simple manual way to do so is to loop over digits beginning with the index ndigits - 1 and looping ndigits times for each group manually converting the digits to int. Only positive values of the groupings are considered, which reduces the task to:
/* loop starting at ndigits digit, combine every ndigits digits into int
* (only positive combinations are considered)
*/
for (int i = ndigits - 1; digits[i]; i++) {
int j = i, /* index for scanning over digits to separate */
n = ndigits, /* copy of number of digits to separate */
num = 0, /* separated number */
mult = 1; /* digit multiplier */
while (n--) { /* loop ndigits times */
num += mult * (digits[j--] - '0'); /* add mult * value to num */
mult *= 10; /* increment mult by 10 */
}
printf (" %*d\n", ndigits, num); /* (optional) output of num */
/** check if num is prime here **/
}
That's it. Checking for prime is left to you. The input, grouping and conversion of the group to int can be checked by printing each grouping that would be checked for prime.
Example Use/Output
Putting the code together (a complete source is provided at the end), compiling and running your would get:
$ ./bin/group-digits
enter number : 1234
combine ndigits : 1
1
2
3
4
Groupings of two:
$ ./bin/group-digits
enter number : 1234
combine ndigits : 2
12
23
34
Groupings of three:
$ ./bin/group-digits
enter number : 1234
combine ndigits : 3
123
234
Groupings of four:
$ ./bin/group-digits
enter number : 1234
combine ndigits : 4
1234
What about a grouping of five with four-digits?
$ ./bin/group-digits
enter number : 1234
combine ndigits : 5
error: requested combination of digits not possible.
What about a larger string of digits, that itself exceeds the size of int, but so long as the group-size is within the size of int, there is no reason that wouldn't work:
$ ./bin/group-digits
enter number : 12345678901234567890
combine ndigits : 4
1234
2345
3456
4567
5678
6789
7890
8901
9012
123
1234
2345
3456
4567
5678
6789
7890
(note: 0123 is properly converted to 123 instead of an octal value representing 83)
Complete Source for Example
The complete combined source code for the example for easy reference is:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXDIGITS BUFSIZ
/* simple function checks if s is composed of all digits,
* returns 1 if so, 0 otherwise.
*/
int all_digits (const char *s)
{
int i = 0;
if (!*s || *s == '\n') { /* check empty-string or empty-line */
return 0;
}
for (; s[i]; i++) { /* loop over each digit */
if (!isdigit((unsigned char)s[i])) {
break;
}
}
return !s[i]; /* end-of-string */
}
int main (void) {
char buf[MAXDIGITS], /* general input buffer */
digits[MAXDIGITS]; /* buffer to hold digits */
int ndigits = 0; /* digits to separate and test */
/* read/validate input A */
fputs ("enter number : ", stdout);
if (!fgets (digits, sizeof digits, stdin)) {
puts ("(user canceled input)");
return 0;
}
digits[strcspn (digits, "\n")] = 0; /* trim trailing '\n' */
if (!all_digits (digits)) { /* validate input all digits */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
/* read / validate input B */
fputs ("combine ndigits : ", stdout);
if (!fgets (buf, sizeof buf, stdin)) {
puts ("(user canceled input)");
return 0;
}
/* convert string to int / validate */
if (sscanf (buf, "%d", &ndigits) != 1) {
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
/* validate the number of digits to combine is possible */
if (ndigits <= 0 || (size_t)ndigits > strlen (digits)) {
fputs ("error: requested combination of digits not possible.\n",
stderr);
return 1;
}
/* loop starting at ndigits digit, combine every ndigits digits into int
* (only positive combinations are considered)
*/
for (int i = ndigits - 1; digits[i]; i++) {
int j = i, /* index for scanning over digits to separate */
n = ndigits, /* copy of number of digits to separate */
num = 0, /* separated number */
mult = 1; /* digit multiplier */
while (n--) { /* loop ndigits times */
num += mult * (digits[j--] - '0'); /* add mult * value to num */
mult *= 10; /* increment mult by 10 */
}
printf (" %*d\n", ndigits, num); /* (optional) output of num */
/** check if num is prime here **/
}
}
If The Groups Are Exclusive
If you intended your groupings to be exclusive, meaning if you had ten-digits, "0123456789" and wanted groups of five digits, that would provide two exclusive integers 1234 and 56789, then there are a few easy changes to make.
As a convenience, you can save the length of digits at the same time you trim the '\n' from the end, e.g.
...
int main (void) {
char buf[MAXDIGITS], /* general input buffer */
digits[MAXDIGITS]; /* buffer to hold digits */
int ndigits = 0; /* digits to separate and test */
size_t len = 0; /* length of digits */
...
digits[(len = strcspn (digits, "\n"))] = 0; /* trim '\n' save len */
...
You need to ensure len is divisible by ndigits, so just add your check to the existing checks for combinations
/* validate the number of digits to combine is possible */
if (ndigits <= 0 || (size_t)ndigits > len || len % ndigits ) {
fputs ("error: requested combination of digits not possible.\n",
stderr);
return 1;
}
Finally adjust your for loop increment:
/* loop starting at ndigits digit, combine every ndigits digits into int
* (only positive combinations are considered)
*/
for (int i = ndigits - 1; digits[i]; i += ndigits) {
...
Modified Example Use / Output
Now only exclusive ranges of digits are considered for the check against prime:
./bin/group-digits2
enter number : 12345678901234567890
combine ndigits : 4
1234
5678
9012
3456
7890
Or by groups of 5:
$ ./bin/group-digits2
enter number : 12345678901234567890
combine ndigits : 5
12345
67890
12345
67890
If len isn't divisible by ndigits:
$ ./bin/group-digits2
enter number : 12345678901234567890
combine ndigits : 6
error: requested combination of digits not possible.
Let me know if you have questions.
Can someone help me with this? I want to write a code that will print random even number "i" times. Here "i" is variable and input (i is always greater than 0). Example: Input (4) I want output to be (4,4,4,4), Input (2) I want output to be (2,2). I want to print the number many times mentioned in the input. Here is the question
Here, the term "random" may not be appropriate.
In order to achieve this, you can:
get the numerical representation of the user input. To do so you can use strtol which returns a number.
use a for-loop print the N occurrences using the standard printf function along with the number formatter %d.
For instance:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int number;
int i;
/* `argc` contains the total number of arguments passed to the
* application. There is always at least one argument (i.e.: the
* application name). Here, we ensure the user has given a argument
* which we expect to be the number (i).
*
* If there are less than two arguments given then the user has
* not passed anything => the command line was "$ ./a.out". */
if (argc < 2) {
goto usage;
}
/* Get the user input number by parsing the user given argument.
* As arguments are string of characters, this function transforms
* the string "1234" into 1234. The result is a number we will be
* able to manipulate (add, sub, mul, div, etc.). */
char *endptr;
number = strtol(argv[1], &endptr, 10);
/* We want to ensure the input was really a number.
* The `strtol` function provides a way to verify whether the
* given string is correctly formatted by giving the last character
* of the string. In case the number is not formatted correctly,
* then the last char is not the NULL terminating char. */
if (*endptr != '\0') {
goto usage;
}
/* Ensure the number is positive. */
if (number < 0) {
goto usage;
}
/* This for loop executes "number" of times. We have a counter
* `i` which value will be incremented from [ 0 to "number" [.
* Each time we execute the loop, we print the number. */
for (i = 0; i < number; i++) {
printf("%d ", number);
}
printf("\n");
return 0;
usage:
// TODO
return 1;
}
The easiest way is to read input from the user and just display the number "n" times. Here's an example:
#include <stdio.h>
int main(int argc, char **argv) {
int user_input, is_correct; // user_input is a number to be displayed
// scanf reads input from the user, %d is an integer
is_correct = scanf("%d", &user_input);
// check if user entered a number
if(!is_correct) {
printf("Incorrect input, enter number!");;
return -1;
}
// check if number is even
if(user_input % 2 != 0) {
printf("Number is not even, try again!");
return -1;
}
// display number
for(int i = 0; i < user_input; ++i) {
printf("%d ", user_input);
}
return 0;
}
I'm writing a code in C to find the digits that repeat in a given number, and the one that I wrote works fine for small numbers, but the output gets messed up if I input a large value, N < 1000.
Here is my code; please help me out!
For the input:
1839138012980192380192381090981839
I get this output:
0 2 3 5 7 8
#include <stdio.h>
int main()
{
int digit, digits[10], flag = 0, i;
long long num;
scanf("%lld", &num);
while (num)
{
digit = num % 10;
if (digits[digit])
flag = 1;
digits[digit]++;
num /= 10;
}
if (flag)
{
for (i = 0; i < 10; i++)
{
if (digits[i] > 1)
printf("%d ", i);
}
printf("\n");
}
else
printf("The are no repeated digits.\n");
return 0;
}
The long long type can only represent a limited range of numbers. In your C implementation, 1839138012980192380192381090981839 is too big for long long, and scanf("%lld", &num) does not work.
Instead, read each character of input using c = getchar();, where c is declared as an int. If, after getchar, c is EOF, stop looping and print the results. If c is not EOF, then check whether it is a digit using if (isdigit((unsigned char) c)). The isdigit function is defined in <ctype.h>, so include that header.
If the character is a digit, then convert it from a character to the number it represents using c - '0'. You can use int d = c - '0'; to store the number in d. Then increment the count for the digit d.
If the character is not a digit, you can decide what to do:
There will likely be a new-line character, '\n', at the end of the line the user entered. You may want to ignore it. When you see the new-line, you could end the loop and print the results, you could continue reading to see if there are any other digits or characters before EOF is seen and report a problem to the user if there are, or you could ignore it and continue looping.
There could be spaces in the input. You might want to ignore them, or you might want to report a problem to the user.
If there are other characters, you might want to report a problem to the user.
Here's another approach, which you could use with a string of some maximum length (defined by the constant MAX_LEN).
A string made up of a bunch of char will use one byte per character, so you can define MAX_LEN up to how many bytes you have in system memory, generally, although in practice you probably would use a much smaller and more reasonable number.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 12345
int main()
{
int digit, digits_checker[10] = {0}, flag = 0, i;
char* num;
/* set aside space for the string and its terminator */
num = malloc(MAX_LEN + 1);
/* read num from input */
scanf("%s", num);
/* get the string length */
size_t num_length = strlen(num);
/* walk over every character in num */
for (size_t position = 0; position < num_length; position++)
{
/*
We assume that the value of num[position] is an
ASCII character, from '0' to '9'. (If you can't make
that assumption, check the input and quit with an
error, if a non-digit character is found.)
If the input is valid, the digits 0-9 in the ASCII
table start at 48 ('0') and end at 57 ('9'). Subtracting
48, therefore, gives you the integer value at each digit
in num.
*/
digit = num[position] - 48;
/*
Increment a counter for each digit
*/
digits_checker[digit]++;
}
/* num is no longer needed, so we free its memory */
free(num);
/* check each digit */
for (i = 0; i < 10; i++)
{
if (digits_checker[i] > 1) {
printf("%d ", i);
flag = 1;
}
}
if (!flag) {
printf("The are no repeated digits.\n");
}
else {
printf("\n");
}
return 0;
}
The suggestion to check input is a good one. You can't necessarily assume that what someone enters will be entirely made up of digit characters.
But hopefully this demonstrates how to set aside space for a string, and how to read through it, one character at a time.
I need to convert 3 digit decimal number to binary using C.
My code:
#include <stdio.h>
#define TWO 2
int main() {
int dec_num; // demical number
int i = 0; // loop cunter
printf("type in 3 digits number to convert to binary\n");
scanf("%d", &dec_num);
while (++i <= 12) {
if (dec_num % TWO != 0) {
printf("1") ;
} else if (dec_num % TWO == 0) {
printf("0");
} else if (dec_num <= 0) {
break;
}
dec_num / TWO;
}
return 0;
}
The problem is that the number doesn't get divided by 2 at the end of the while loop how can I fix it?
You did not store the value of dec_num after the division.
dec_num / TWO; //<--------------------
Your while loop condition was also wrong.
while(++i <= 12) //<-------------------
You should perform the division operation until the number is greater than 0
According to the rules of binary to decimal, you should print 1s and 0s in reverse order. But in your code, you have changed the order. In order to fix that We could store the result in an array and then we could print the result in reverse order.
Here is your modified code,
#include <stdio.h>
#define TWO 2
int main()
{
int dec_num; // demical number
int i=0; // loop cunter
printf("type in 3 digits number to convert to binary\n");
int flag = scanf("%d",&dec_num); //<-----check the user input
if(flag!=1)
{
printf("Input is not recognized as an integer");
return 0;
}
int size=0;
int array[120] = {0}; //<-------to store the result
while(dec_num > 0){ //<------- while the number is greater than 0
if(dec_num % TWO !=0){
array[i] = 1;
}
else if(dec_num % TWO ==0){
array[i] = 0;
}
size = ++i; //<------- store the size of result
dec_num = dec_num / TWO; //<------- divide and modify the original number
}
for(i=size-1;i>=0;i--) //<------- print in reverse order
printf("%d",array[i]);
return 0;
}
My solution will assume that the input is a positive number and that maximal decimal 3 digit number can be presented by 10 bits (decimal 999 is binary 1111100111). I will also use the fact that the bit-wise operators are defined by the C standard and should take place. These operations on most of the architectures are very efficient and much faster than / or %.
#include <stdio.h>
#define MAX_BIN_DIGITS 10
#define ERR_INVALID_INPUT_VALUE 1
int main(void)
{
int dec_num; // demical input number
int i = MAX_BIN_DIGITS;
int bin_bit;
// storing the result at zero terminated string
char bin_res[MAX_BIN_DIGITS+1] = {0};
printf("Type in 3 digits number to convert to binary:\n");
if (1 != scanf("%d",&dec_num))
{
printf("Error: Invalid input value!");
return ERR_INVALID_INPUT_VALUE;
}
// Checking for 'i' here just to be safe in case of larger input than expected - 4 digits or more
while(i-- && dec_num)
{
bin_bit = dec_num & 1; // get the LSB
dec_num >>= 1; // remove the LSB from 'dec_num'
bin_res[i] = '0' + bin_bit; // store the LSB at the end as a char
}
// Print the array starting from the most significant bit which is '1'
// NOTE: Need to take care of special case when the input is '0', then 'i'
// will be equal to 'MAX_BIN_DIGITS-1'.
printf("%s\n", (i != MAX_BIN_DIGITS-1) ? &(bin_res[i+1]) ? "0");
return 0;
}
There are multiple problems in your code:
You do not test the return value of scanf(): you get undefined behavior if the user fails to input characters that can be converted to an integer.
You do not test if the number indeed has at most 3 digits.
You iterate up to 12 times, but 10 should suffice since 210 = 1024 which is greater than any 3 digit number
As a matter of fact, it should not even be necessary to limit the number of iterations, since you stop when the number drops to 0.
The tests are inconsistent: num % TWO is either 0 or 1, the second test is redundant and the third test is never executed, so the loop fails to detect proper termination condition.
dec_num / TWO; does not update dev_num, so your loop just keeps printing the least significant bit (and the test while (++i <= 12) is indeed necessary for the loop to stop).
if corrected, this loop would print the bits from the least significant to the most significant, which is probably not the expected behavior.
#define TWO 2 is not strictly speaking a mistake, but does not improve code readability or safety. Local coding rules might bar you from using non trivial numeric constants in the code: such a rule seems counter productive in this particular case.
It is considered good style to always end output lines with a newline.
beware of typos: demical number is cute and loop cunter is intriguing.
Here is a corrected version of your code, using your algorithm, to illustrate the unexpected output (last significant bit to most significant bit):
#include <stdio.h>
int main() {
int dec_num; // decimal number
printf("type in a 3 digit number to convert to binary\n");
if (scanf("%d", &dec_num) != 1) {
printf("invalid input\n");
return 1;
}
if (dec_num < 0 || dec_num > 999) {
printf("invalid value: must have at most 3 digits\n");
return 1;
}
for (;;) {
if (dec_num % 2 != 0) {
printf("1");
} else {
printf("0");
}
dec_num = dec_num / 2;
if (dec_num == 0)
break;
}
printf("\n");
return 0;
}
Here is a recursive version that outputs the bits in the proper order:
#include <stdio.h>
void output_binary(int num) {
if (num > 1)
output_binary(num / 2);
printf("%d", num % 2);
}
int main() {
int dec_num; // decimal number
printf("type in a 3 digit number to convert to binary\n");
if (scanf("%d", &dec_num) != 1) {
printf("invalid input\n");
return 1;
}
if (dec_num < 0 || dec_num > 999) {
printf("invalid value: must have at most 3 digits\n");
return 1;
}
output_binary(dec_num);
printf("\n");
return 0;
}
While you already have a valid answer correcting the failure to update dec_num following division and valid recursive methods provided by others, it is unclear whether you intend to allow entry of negative 3-digit values as well as positive values. An implementation that determines the size of the type and then shifts by one over each of the bits can provide a simple solution that will handle both positive and negative values.
For example the conversion part of the code shifting by 1 for each bit (indexed 31 -> 0) could be as simple as:
int main (void) {
int decnum = 0; /* user input number */
unsigned remain = 0; /* remainder after shift */
size_t nbits = sizeof decnum * CHAR_BIT; /* number of bits for type */
/* read decnum here */
printf ("decimal: %d\nbinary : ", decnum); /* output value */
while (nbits--) { /* write bits 31->0 while 1 bits remain */
if ((remain = decnum >> nbits)) /* shift saving shifted value */
putchar ((remain & 1) ? '1' : '0'); /* bit 0/1 output '0'/'1' */
}
putchar ('\n'); /* tidy up with newline */
}
(note: a simple ternary operator is used to determine whether to output '1' or '0')
The bigger part of your problem is the your failure to check the return of scanf. This is an open invitation for Undefined Behavior. Regardless of what function you use for user-input, you must validate that input succeeded before proceeding further. Otherwise you will invoke undefined behavior when you attempt to access an indeterminate value.
When using scanf in order to require valid input, you must handle three cases each time (1) did the user cancel input by pressing Ctrl+d generating a manual EOF? (Ctrl+z on windows), (2) did a matching or input failure occur? and (3) the good input case. Then, as is your case, you must further validate the input was in the proper range of values (a 3 digit number in your case). Additionally, to require valid input, you must handle any character that remains unread in the input buffer (as is the case for a matching failure, or if the user slipped and typed additional characters after the integer value.
Now it is completely fine to simply validate the input and return on an invalid input regardless of what caused the failure, but to require valid input it is up to you to handle all three cases, check that the input was within the valid range (and even then remove the trailing '\n' left by scanf preparing the input-buffer for whatever additional input may be taken later in your code.
Many times that will require more code than your actual calculation does, but it is critical. For instance in your case, if you wanted to require the user to enter valid input, you could replace the /* read decnum here */ with something similar to:
for (;;) { /* loop continually until valid input or canceled */
int rtn; /* variable to hold scanf return */
fputs ("enter 3 digit integer: ", stdout); /* prompt */
rtn = scanf ("%d", &decnum); /* read value, saving return */
if (rtn == EOF) { /* handle manual EOF cancelation */
fputs ("(user canceled input)\n", stderr);
return 1;
}
if (rtn == 0) { /* handle input failure */
empty_stdin(); /* always empty input buffer */
fputs (" error: invalid integer input.\n", stderr);
} /* validate 3 digit poisitive (or negative) number */
else if (decnum < -999 || (decnum > -100 && decnum < 100)
|| decnum > 999) {
empty_stdin();
fputs (" error: not a 3 digit number.\n", stderr);
}
else { /* handle good input case (break loop) */
empty_stdin();
break;
}
}
note: the helper function empty_stdin(). That can be implemented with getchar() to read and discard any characters causing problems, e.g.
void empty_stdin (void) /* helper function to empty stdin after bad input */
{ /* (as well as the trailing '\n' after good input) */
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
Putting it altogether, you could do something like the following:
#include <stdio.h>
#include <limits.h> /* for CHAR_BIT */
void empty_stdin (void) /* helper function to empty stdin after bad input */
{ /* (as well as the trailing '\n' after good input) */
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int decnum = 0; /* user input number */
unsigned remain = 0; /* remainder after shift */
size_t nbits = sizeof decnum * CHAR_BIT; /* number of bits for type */
for (;;) { /* loop continually until valid input or canceled */
int rtn; /* variable to hold scanf return */
fputs ("enter 3 digit integer: ", stdout); /* prompt */
rtn = scanf ("%d", &decnum); /* read value, saving return */
if (rtn == EOF) { /* handle manual EOF cancelation */
fputs ("(user canceled input)\n", stderr);
return 1;
}
if (rtn == 0) { /* handle input failure */
empty_stdin(); /* always empty input buffer */
fputs (" error: invalid integer input.\n", stderr);
} /* validate 3 digit poisitive (or negative) number */
else if (decnum < -999 || (decnum > -100 && decnum < 100)
|| decnum > 999) {
empty_stdin();
fputs (" error: not a 3 digit number.\n", stderr);
}
else { /* handle good input case (break loop) */
empty_stdin();
break;
}
}
printf ("decimal: %d\nbinary : ", decnum); /* output value */
while (nbits--) { /* write bits 31->0 while 1 bits remain */
if ((remain = decnum >> nbits)) /* shift saving shifted value */
putchar ((remain & 1) ? '1' : '0'); /* bit 0/1 output '0'/'1' */
}
putchar ('\n'); /* tidy up with newline */
}
Example Use/Output
$ ./bin/prnbin3digit
enter 3 digit integer: why?
error: invalid integer input.
enter 3 digit integer: -75
error: not a 3 digit number.
enter 3 digit integer: 1024
error: not a 3 digit number.
enter 3 digit integer: 127 and more junk
decimal: 127
binary : 1111111
Or the case with a negative value:
$ ./bin/prnbin3digit
enter 3 digit integer: -127
decimal: -127
binary : 11111111111111111111111110000001
Or the case where the user cancels input:
$ ./bin/prnbin3digit
enter 3 digit integer: (user canceled input)
While this ended up being longer than what a simple right-shift implementation of the conversion would have been, it is worth building good user-input habits now to avoid untold problems later. Look things over and let me know if you have further questions.
I'm having troubles with my program. The aim of it is to read an input of numbers from the user, and when they stop inputting numbers (ctrl-d) it collects the inputted numbers and prints out 'Odd numbers were: blah blah'
and 'Even numbers were: blah blah'.
I'm having trouble with how to exit the program at EOF and when it feels like I have overcome that problem, another problem occurs which is my program doesn't print the numbers from the array. It only prints 'Odd numbers were:' and 'Even numbers were:'.
Any help is appreciated.
Thanks
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void) {
int n, i, array[1000];
i=0;
while (i = getchar() !=EOF) {
scanf("%d", &array[i]);
i++;
}
printf("Odd numbers were:");
i=0 ;
while(i = getchar() != EOF) {
if(array[i]%2!=0) {
printf(" %d", array[i]);
i++;
}
}
printf("\nEven numbers were:");
i=0 ;
while(i = getchar() !=EOF) {
if (array[i]%2==0) {
printf(" %d", array[i]);
i++;
}
}
printf("\n");
return 0;
}
Performing Single-Digit Conversion to int
You may be making things a bit harder on yourself than it needs to be. While you can use while (scanf ("%d", &array[i]) == 1) to read whitespace separated integers and avoid having to perform a manual conversion, if your intent is to read single-digits, then using getchar() is fine. (for that matter, you can read any multi-digit integer with getchar(), it is simply up to you to provide a conversion from the ASCII characters to final numeric value)
The manual conversion for single-digit characters is straight forward? When you read digits as characters, you are not reading the integer value represented by the digit, you are reading the ASCII value for the character that represents each digit. See ASCII Table and Description. In order to convert a single ASCII character digit to it's integer value, you must subtract the ASCII value of '0'. (note: the single-quotes are significant)
For example if you read a digit with int c = getchar();, then you need to subtract '0' to obtain the single-digit integer value, e.g. int n = c - '0';
When filling an array, you must ALWAYS protect against writing beyond the bounds of your array. If you declare int array[1000] = {0}; (which has available zero-based array indexes of 0-999), then you must validate that you never write beyond index 999 or Undefined Behavior results. To protect your array bounds, simply keep track of the number of indexes filled and test it is always below the number of array elements available, e.g.
while (n < MAX && (c = getchar()) != EOF) /* always protect array bounds */
if ('0' <= c && c <= '9') /* only handle digits */
array[n++] = c - '0'; /* convert ASCII to int */
Next, while you are free to test n % 2 (using the modulo operator), there is no need (little endian). Since any odd number will have its ones-bit set to 1, all you need is a simple bitwise comparison, e.g (7 in binary is 0111).
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
Of course, for even numbers, the ones-bit will be 0 (e.g. 8 in binary is 1000), so the corresponding test can be:
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
Putting all of the pieces together, you can store all single digits read in array and then segregate the even and odd numbers for printing in a very simple manner (note: neither stdlib.h or math.h are required),
#include <stdio.h>
#define MAX 1000 /* define a constant rather than use 'magic' numbers in code */
int main (void)
{
int array[MAX] = {0},
c, i, n = 0;
while (n < MAX && (c = getchar()) != EOF) /* always protect array bounds */
if ('0' <= c && c <= '9') /* only handle digits */
array[n++] = c - '0'; /* convert ASCII to int */
printf ("\narray : "); /* output array contents */
for (i = 0; i < n; i++)
printf (" %d", array[i]);
printf ("\narray - odd : ");
for (i = 0; i < n; i++)
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
printf ("\narray - even : ");
for (i = 0; i < n; i++)
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
putchar ('\n'); /* tidy up w/newline */
return 0;
}
Example Compilation with Warnings Enabled
$ gcc -Wall -Wextra -pedantic-std=gnu11 -Ofast -o bin/arrayevenodd arrayevenodd.c
Example Use/Output
$ echo "01234567890123456789" | ./bin/arrayevenodd
array : 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
array - odd : 1 3 5 7 9 1 3 5 7 9
array - even : 0 2 4 6 8 0 2 4 6 8
Look things over and let me know if you have further questions.
Performing Manual Multi-Digit Conversion to int
If you are needing to convert multi-digit integers from characters, the easy way is to use a function that provides the conversion for you (e.g. the scanf family of functions or by using line oriented with fgets or getline and parsing and converting the strings of digits with strtok and then strtol, or parsing with sscanf, etc.)
However, performing a manual conversion of individual characters read by getchar() into a multi-digit integers is straight forward. You simply check for a valid character than can begin an integer (including the prefixes of +/-) and sum each digit providing a proper offset for the place of the digit by increasingly multiplying the sum by 10 before adding (or actually subtracting if building a the sum as a negative sum for coding efficiency purposes) each digit until you reach the next non-digit and then you add the final sum to your array and advance the array index.
While building the sum, it is up to you to check for integer Overflow before adding the final sum to your array. (you can handle the overflow condition however you like, the example below just throws the error and exits)
The manual conversion probably adds about 20 lines of code, e.g.
#include <stdio.h>
#include <stdint.h> /* exact length types */
#include <limits.h> /* INT_X constants */
#define MAX 1000 /* define constant rather than use 'magic' number in code */
int main (void)
{
int array[MAX] = {0},
c, i, start = 0, sign = 1, n = 0;
int64_t sum = 0;
while (n < MAX && (c = getchar()) != EOF) { /* always protect array bounds */
if (!start) { /* flag to start building int */
start = 1; /* flag - working on int */
if (c == '+') /* handle leading '+' sign */
continue;
else if (c == '-') /* handle leading '-' sign */
sign = -1;
else if ('0' <= c && c <= '9') /* handle digits */
sum = sum * 10 - (c - '0'); /* note: sum always computed */
else /* as negative value */
start = 0; /* reset - char not handled */
}
else if ('0' <= c && c <= '9') { /* handle digits */
sum = sum * 10 - (c - '0'); /* convert ASCII to int */
if (sum < INT_MIN || (sign != -1 && -sum > INT_MAX))
goto err; /* check for overflow, handle error */
}
else { /* non-digit ends conversion */
if (sum) /* if sum has value, add to array */
array[n++] = sign != -1 ? -sum : sum;
sign = 1; /* reset values for next conversion */
start = 0;
sum = 0;
}
}
if (sum) /* add last element to array on EOF */
array[n++] = sign != -1 ? -sum : sum;
printf ("\narray : "); /* output array contents */
for (i = 0; i < n; i++)
printf (" %d", array[i]);
printf ("\narray - odd : ");
for (i = 0; i < n; i++)
if (array[i] & 1) /* if ones-bit is 1, odd */
printf (" %d", array[i]);
printf ("\narray - even : ");
for (i = 0; i < n; i++)
if ((array[i] & 1) == 0) /* if ones-bit is 0, even */
printf (" %d", array[i]);
putchar ('\n'); /* tidy up w/newline */
return 0;
err:
fprintf (stderr, "error: overflow detected - array[%d]\n", n);
return 1;
}
Example Use/Output
$ echo "1,2,3,5,76,435" | ./bin/arrayevenodd2
array : 1 2 3 5 76 435
array - odd : 1 3 5 435
array - even : 2 76
Example with '+/-' Prefixes
$ echo "1,2,-3,+5,-76,435" | ./bin/arrayevenodd2
array : 1 2 -3 5 -76 435
array - odd : 1 -3 5 435
array - even : 2 -76
Look over the new example and let me know if you have any more questions.
Change the input loop to:
n = 0;
while ( 1 == scanf("%d", &array[n]) )
++n;
What you actually want to do is keep reading numbers until the read attempt fails; this loop condition expresses that logic. Forget about EOF. (It would also be a good idea to add logic to stop when n reaches 1000, to avoid a buffer overflow).
In the output loops, you do not want to do any input, so it is not a good idea to call getchar(). Instead, use a "normal" loop, for (i = 0; i < n; ++i).