Restrict user input to 5 digits in C - c

I was assigned to make an user input a 5 digit number, validate it and print it back in a reversed order, I have the reverse part figured out yet I am struggling to figure out how to validate the variable in order to force the user to use 5 digits
#include <stdio.h>
int main() {
int n, inv = 0, inverso;
printf("Introduce un numero de 5 digitos: ");
scanf("%d", &n);
while (n != 0) {
inverso = n % 10;
inv = inv * 10 + inverso;
n /= 10;
}
printf("El numero invertido es = %d", inv);
return 0;
}

I would read into a character string, validate that the length is 5, and all characters are digits. Prompt to repeat if validation failed.
Then simply print that string in reverse order.
For example:
int n, inv = 0, inverso;
char buff[100];
int repeat = 1;
while (repeat) {
printf("Introduce un numero de 5 digitos: ");
scanf("%s", buff);
repeat = 0;
if (strlen(buff) != 5) {
printf("You must type 5 digits\n");
repeat = 1;
continue;
}
for (int i = 0; i < 5; ++i) {
if (!isdigit(buff[i])) {
printf("%c is not a digit\n");
repeat = 1;
continue;
}
}
}
printf("\nEl numero invertido es = ");
for (int i = 4; i >= 0; --i) {
printf("%c", buff[i]);
}

You could reject the input if it is greater than 5 and signal it to the user, or you could truncate the input (after validating it) to prevent overflowing the maximum size. For instance :
if (strlen(string) > 5) string[5] = '\0';
Then continue normally (possibly signaling to the user that its input has been truncated) (the advantage being not to force the user to input again).

Since you're already processing the user input number digit-by-digit in a loop, it makes sense to just add a count variable initialized at 0 that increments each loop iteration:
int count = 0;
while (n != 0) {
inverso = n % 10;
inv = inv * 10 + inverso;
n /= 10;
count++;
}
There are count digits in your user's input.
That said, in this case, unless your homework assignment or exercise prohibit processing the user input as a string instead of an integer, that really is the way to go because it's a lot simpler.

Use fgets() to read the input as a string. Later validate that the input is no longer that 5 digits and parse it with sscanf(). Even better you can avoid converting it and just print it in reverse.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LENGTH 500
int main()
{
char buff[500] = {0};
char *numbers = "0123456789";
if (!fgets(buff,MAX_LENGTH,stdin))
{
fprintf(stderr,"input error...\n");
exit(EXIT_FAILURE);
}
buff[strcspn(buff, "\n")] = 0; /* removing newline character from the buffer */
if (strspn(buff,numbers) != strlen(buff)) /* making sure input is only numbers */
{
printf("only numbers allowed\n");
exit(EXIT_FAILURE);
}
for (size_t i = 0, len = strlen(buff); i <= len; i++)
{
putchar(buff[len-i]);
}
return 0;
}
sscanf() alternative :
if (!fgets(buff,MAX_LENGTH,stdin))
{
fprintf(stderr,"input error...\n");
exit(EXIT_FAILURE);
}
if (sscanf(buff,"%ld",&number) != 1) /* always check the result of scanf() */
{
fprintf(stderr,"input failure\n");
exit(EXIT_FAILURE);
}
/* reverse the number */

Here is a simple test to check that n has 5 digits:
if (n >= 10000 && n <= 99999) {
// n has 5 digits
} else {
// try again
}
Here is a modified version:
#include <stdio.h>
int main() {
int c, n, inv;
for (;;) {
printf("Introduce un numero de 5 digitos: ");
if (scanf("%d", &n) == 1 && n >= 10000 && n <= 99999)
break;
while ((c = getchar()) != '\n') {
if (c == EOF) // unexpected end of file
return 1;
}
printf("Invalid input, try again\n");
}
inv = 0;
while (n != 0) {
inv = inv * 10 + n % 10;
n /= 10;
}
printf("El numero invertido es = %d\n", inv);
return 0;
}

I would try a more unorthodox way since your input is already a String(char).
#include <stdio.h>
int len;
char buff[100];
int main()
{
scanf("%s", buff);
len = strlen(buff);
}
From there you have the length of the string stored in an int form in variable len.
You will continue by coding the if that handles what happens when len is greater than 5.
Hope i helped!

Related

how to extract the even number from user input, and combine them as a new number in C program

test case:
input: 1234
output: 24
input: 2468
output: 2468
input: 6
output: 6
I have this code:
#include <stdio.h>
#include <math.h>
int main() {
int num;
printf("Enter a number: \n");
scanf("%d", &num);
int numberLength = floor(log10(abs(num))) + 1;
int inputNumberArray[numberLength];
int evenNumberCount = 0;
int even[10];//new even no. array
int i = 0;
do {
inputNumberArray[i] = num % 10;
num = num / 10;
i++;
} while (num != 0);
i = 0;
while (i < numberLength) {
if (inputNumberArray[i] % 2 == 0) {
evenNumberCount ++;
even[i] = inputNumberArray[i];
}
i++;
}
printf("array count %d\n", evenNumberCount);
i = 0;
for (i = 0; i < 8; i++) {
printf(" %d", even[i]);//print even array
}
i = 0;
int result = 0;
for (i = 0; i < 10; i++) {
if (evenNumberCount == 1) {
if (even[i] != 0) {
result = even[i];
} else {
break;
}
} else {
if (even[i] != 0) {
result = result + even[i] * pow(10, i);
} else
break;
}
}
printf("\nresult is %d", result);
/*
int a = 0;
a = pow(10, 2);
printf("\na is %d", a);
*/
}
when I enter number 1234, the result/outcome is 4, instead of 24.
but when I test the rest of test case, it is fine.
the wrong code I think is this: result = result + even[i] * pow(10, i);
Can you help on this?
Thanks in advance.
why do you have to read as number?
Simplest algorithm would be
Read as text
Validate
loop through and confirm if divisible by 2 and print live
next thing, have you try to debug?
debug would let you know what are doing wrong. Finally the issue is with indexing.
evenNumberCount ++; /// this is technically in the wrong place.
even[i]=inputNumberArray[i]; /// This is incorrect.
As the user Popeye suggested, an easier approach to accomplish this would be to just read in the entire input from the user as a string. With this approach, you can iterate through each letter in the char array and use the isdigit() method to see if the character is a digit or not. You can then easily check if that number is even or not.
Here is a quick source code I wrote up to show this approach in action:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char input[100] = { '\0' };
char outputNum[100] = { '\0' };
// Get input from user
printf("Enter a number: ");
scanf_s("%s", input, sizeof(input));
// Find the prime numbers
int outputNumIndex = 0;
for (int i = 0; i < strlen(input); i++)
{
if (isdigit(input[i]))
{
if (input[i] % 2 == 0)
{
outputNum[outputNumIndex++] = input[i];
}
}
}
if (outputNum[0] == '\0')
{
outputNum[0] = '0';
}
// Print the result
printf("Result is %s", outputNum);
return 0;
}
I figured out the solution, which is easier to understand.
#include <stdio.h>
#include <math.h>
#define INIT_VALUE 999
int extEvenDigits1(int num);
void extEvenDigits2(int num, int *result);
int main()
{
int number, result = INIT_VALUE;
printf("Enter a number: \n");
scanf("%d", &number);
printf("extEvenDigits1(): %d\n", extEvenDigits1(number));
extEvenDigits2(number, &result);
printf("extEvenDigits2(): %d\n", result);
return 0;
}
int extEvenDigits1(int num)
{
int result = -1;
int count = 0;
while (num > 1) {
int digit = num % 10;
if (digit % 2 == 0) {
result = result == -1 ? digit : result + digit * pow(10, count);
count++;
}
num = num / 10;
}
return result;
}
}
You are overcomplicating things, I'm afraid.
You could read the number as a string and easily process every character producing another string to be printed.
If you are required to deal with a numeric type, there is a simpler solution:
#include <stdio.h>
int main(void)
{
// Keep asking for numbers until scanf fails.
for (;;)
{
printf("Enter a number:\n");
// Using a bigger type, we can store numbers with more digits.
long long int number;
// Always check the value returned by scanf.
int ret = scanf("%lld", &number);
if (ret != 1)
break;
long long int result = 0;
// Use a multiple of ten as the "position" of the resulting digit.
long long int power = 1;
// The number is "consumed" while the result is formed.
while (number)
{
// Check the last digit of what remains of the original number
if (number % 2 == 0)
{
// Put that digit in the correct position of the result
result += (number % 10) * power;
// No need to call pow()
power *= 10;
}
// Remove the last digit.
number /= 10;
}
printf("result is %lld\n\n", result);
}
}

Program loops infinitely if a non-integer is entered, and does not accept plural digit inputs

Assigned task is to ask for # of values, and then at the end output the minimum, maximum, and average values and at this point I've run out of bug fixes
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int ErrorDetection = 1;
char valCounter;
int valnumber;
int Incrementer;
int StoredValue;
int MinimumValue = 100;
int MaximumValue = 0;
float Average;
int AddToStored;
int Sum = 0;
printf("MIN, MAX, and MEAN CALCULATOR\n\n");
while (ErrorDetection != 0)
{
printf("How many values are to be entered?\n");
scanf("%s", &valCounter);
if (valCounter > '0' && valCounter < '9') {
ErrorDetection = 0;
}
else {
ErrorDetection = 1;
printf("INPUT ERROR!\n");
}
valCounter = valCounter - 47;
}
for (Incrementer = 1; Incrementer < valCounter; Incrementer++)
{
ErrorDetection = 1;
while (ErrorDetection != 0) {
printf("Value %d: ", Incrementer);
scanf(" %d", &StoredValue);
if (StoredValue > 0 && StoredValue < 9) {
ErrorDetection = 0;
}
else {
ErrorDetection = 1;
printf("INPUT ERROR!\n");
continue;
}
}
if (StoredValue > MaximumValue) {
MaximumValue = StoredValue;
}
if (StoredValue <= MinimumValue) {
MinimumValue = StoredValue;
}
Sum = Sum + StoredValue;
}
valCounter = valCounter - 1;
Average = (float)Sum / (float)valCounter;
printf(
"Minimum value is %d, maximum value is %d, and average value is %g.\n",
MinimumValue, MaximumValue, Average
);
}
If you input a 2 digit number things begin to breakdown, but at the same time I don't know how to go through with errorchecking if I allow multiple digit answers, as I make use of ASCII conversions to check if an input is a number or not.
You have undefined behavior here.
char valCounter;
scanf("%s", &valCounter);
You have declared valCounter as char type but trying to read string type.
Hence change the scanf to.
scanf("%c", &valCounter);
I would suggest you declare valCounter as int
int valCounter;
scanf("%d", &valCounter);
in that case your if will become.
if ((valCounter > 0) && (valCounter < 9))
and you don't need
valCounter = valCounter - 47; //remove
Also your for loop should start from 0 instead of 1
for(Incrementer = 1 ; Incrementer < valCounter; Incrementer++)
should be
for(Incrementer = 0 ; Incrementer < valCounter; Incrementer++)
Your problem is here.
char valCounter;
scanf("%s", &valCounter);
You're telling scanf to read a string, but you're passing it the address of a character. You should be asking for an integer, and giving it the address of an integer.
int valCounter;
scanf("%d", &valCounter)
There's more information here, including reasons why scanf might not be the best idea:
How to scanf only integer?

C program for assigning elements of a matrix without letters

I'm having trouble outputting an invalid statement if the user inputs a letter instead of a number into a 2D array.
I tried using the isalpha function to check if the input is a number or a letter, but it gives me a segmentation fault. Not sure what's wrong any tips?
the following code is just the part that assigns the elements of the matrix.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main() {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
scanf("%d", &n);
if (n <= 1 || n >= 11) { // can't be bigger than a 10x10 matrix
printf("Invalid input.");
return 0;
}
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (!isalpha(matrix[i][j])) { // portion I'm having trouble with
continue;
} else {
printf("Invalid input.");
return 0;
}
}
}
...
As the value of n will be number, we can solve it using string instead of int.
char num[10];
int n;
scanf("%s", num);
if(num[0] < '0' || num[0] > '9' || strlen(num) > 2){
printf("invalid\n");
}
if(strlen(num) == 1) n = num[0] - '0';
if(strlen(num) == 2 && num[0] != 1 && num[1] != 0) printf("invalid\n");
else n = 10;
Also we can use strtol() function to convert the input string to number and then check for validity.You can check the following code for it. I have skipped the string input part. Also you have to add #include<stdlib.h> at the start for the strtol() function to work.
char *check;
long val = strtol (num, &check, 10);
if ((next == num) || (*check != '\0')) {
printf ("invalid\n");
}
if(val > 10 || val < 0) printf("invalid\n");
n = (int)val; //typecasting as strtol return long
You must check the return value of scanf(): It will tell you if the input was correctly converted according to the format string. scanf() returns the number of successful conversions, which should be 1 in your case. If the user types a letter, scanf() will return 0 and the target value will be left uninitialized. Detecting this situation and either aborting or restarting input is the callers responsibility.
Here is a modified version of your code that illustrates both possibilities:
#include <stdio.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main(void) {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
if (scanf("%d", &n) != 1 || n < 2 || n > 10) {
// can't be bigger than a 10x10 matrix nor smaller than 2x2
// aborting on invalid input
printf("Invalid input.");
return 1;
}
for (int i = 0; i < n; i++) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; j++) {
if (scanf("%d", &matrix[i][j]) != 1) {
// restarting on invalid input
int c;
while ((c = getchar()) != '\n') {
if (c == EOF) {
printf("unexpected end of file\n");
return 1;
}
}
printf("invalid input, try again.\n");
j--;
}
}
}
...
The isdigit() library function of stdlib in c can be used to check if the condition can be checked.
Try this:
if (isalpha (matrix[i][j])) {
printf ("Invalid input.");
return 0;
}
So if anyone in the future wants to know what I did. here is the code I used to fix the if statement. I am not expecting to put any elements greater than 10000 so if a letter or punctuation is inputted the number generated will be larger than this number. Hence the if (matrix[i][j] > 10000). May not be the fanciest way to do this, but it works and it's simple.
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (matrix[i][j] > 10000) { // portion "fixed"
printf("Invlaid input");
return 0;
}
}
}
I used a print statement to check the outputs of several letter and character inputs. The lowest out put is around and above 30000. So 10000 I think is a safe condition.

C program to find if a number is palindrome or not

I made a C program to check if a number is palindrome or not. I used the following code, but it shows numbers like 12321 as non palindrome. Can you please explain me the mistake in the program below?
#include <stdio.h>
int main()
{
int i, x, n, c, j;
int d=0;
printf ("enter total digits in number: ");
scanf ("%d", &i);
printf ("\nenter number: ");
scanf ("%d", &n);
j=n;
for (x=1; x<=i; x++)
{
c= j%10;
d=c*(10^(i-x))+d;
j=(j-c)/10;
}
if (d==n)
{
printf ("\npalindrome");
}
else
{
printf ("\nnon palindrome");
}
return 0;
}
^ is the xor operator.
In order to raise power, you need to include math.h and call pow
d = (c * pow(10, i - x)) + d;
this algorithm is as simple as human thinking, and it works
#include <stdio.h>
int main() {
int i=0,n,ok=1;
char buff[20];
printf("Enter an integer: ");
scanf("%d", &n); // i am ommiting error checking
n=sprintf(buff,"%d",n); //convert it to string, and getting the len in result
if(n<2) return 0;
i=n/2;
n--;
while(i && ok) {
i--;
//printf("%c == %c %s\n", buff[i],buff[n-i],(buff[i]==buff[n-i])?"true":"false");
ok &= (buff[i]==buff[n-i]);
}
printf("%s is %spalindrome\n",buff, ok?"":"not ");
return 0;
}
// Yet another way to check for palindrome.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int n, rn, tn;
printf("Enter an integer: ");
scanf("%d", &n);
// reverse the number by repeatedly extracting last digit, add to the
// previously computed partial reverse times 10, and keep dropping
// last digit by dividing by 10
for (rn = 0, tn = n; tn; tn /= 10) rn = rn * 10 + tn % 10;
if (rn == n) printf("%d is palindrome\n", n);
else printf("%d is not palindrome\n", n);
}
A loop like this might do:
int src; // user input
int n; // no of digits
int res = 0;
int tmp; // copy of src
// .... read the input: n and src ....
tmp = src;
for(int i = 0; i < n; i ++)
{
int digit = tmp % 10; // extract the rightmost digit
tmp /= 10; // and remove it from source
res = 10*res + digit; // apend it to the result
}
// ...and test if(res == src)...

Hamming Code - Error Detection & Correction

This question builds on a few other posts. I understand if this is not relevant to most of the people on the internet but at this point, just like anyone else, I am stuck and cannot find the bug in logic. This question requires checking a specified hamming code for a single-bit error and report/correct the error. Here is the program to do so:
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
/** Initializing the global variables */
int MaxLength;
int length;
int parity;
// Initialize the hamming string with a random or NULL memory address
char *HammingString=NULL;
/** Function to enter the values */
void EnterParameters(int *length, int *parity)
{
printf("Enter the maximum length: ");
/** %d reads an integer to be stored in an int. This integer can be signed */
scanf("%d", length);
printf("Enter the parity (0=even, 1=odd): ");
/** %d reads an integer to be stored in an int. This integer can be signed */
scanf("%d", parity);
}
void CheckHamming(char *HammingString, int parity)
{
// Initializing the local variables i, j, k, start, length, ParityNumber
int i, j, k, start, length, ParityNumber;
printf("Enter the Hamming code: ");
scanf("%s", HammingString);
int ErrorBit = 0; // Initialize the error bit
length = strlen(HammingString); // The strlen computes the length of a string up to, but not including the terminating null character
length--;
if (length > MaxLength)
{
printf("\n** Invalid Entry - Exceeds Maximum Code Length of %d\n\n", MaxLength);
return;
}
ParityNumber = ceil(log(length)/log(2)); // The ceil function returns the smallest integer that is greater than or equal to 'x'.
for(i = 0; i < ParityNumber; i++)
{
// pow returns x raised to the power y. In this case, 2 raised to the power i.
start = pow(2, i);
int ParityCheck = parity;
for(j = start; j < length; j=j+(2*start))
{
for(k = j; (k < ((2*j) - 1)) && (k < length); k++)
{
ParityCheck ^= (HammingString[length - k] - '0');
} // End the k for-loop
} // End the j for-loop
ErrorBit = ErrorBit + (ParityCheck * start);
} // End the i for-loop
if(ErrorBit == 0)
{
printf("No error \n");
}
else
{
printf("There is an error in bit: %d\n", ErrorBit);
if(HammingString[length - ErrorBit] == '0')
{
HammingString[length - ErrorBit] = '1';
}
else
{
HammingString[length - ErrorBit] = '0';
}
printf("The corrected Hamming code is: %s \n", HammingString);
}
} // End CheckHamming
int main()
{
int parity;
int choice = 0;
printf("Error detection/correction: \n");
printf("----------------------------\n");
printf("1) Enter parameters \n");
printf("2) Check Hamming code \n");
printf("3) Exit \n");
printf("\nEnter selection: ");
scanf("%d", &choice);
while (choice != 3)
{
if (choice == 1)
{
EnterParameters(&MaxLength, &parity);
HammingString = (char*) malloc (MaxLength * sizeof(char));
main();
}
else if (choice == 2)
{
CheckHamming(HammingString, parity);
main();
}
else
{
printf("Valid options are 1, 2, or 3. Quitting program. \n");
exit(0);
}
}//end while
exit(0);
}//end main
If the hamming code: 1000110 is entered, the hand-calculated error comes out to an error in but 6 with the corrected code being 1100110. This code displays an error in bit 3 with the corrected code being 1000010. Any help is be greatly appreciated.
I can't quite follow how your code is supposed to work. So here's a simple implementation that computes the syndrome for the code 1000110. The output from the program is 6, i.e. the error is in bit 6.
#include <stdio.h>
int main( void )
{ // 7654321
char input[] = "1000110";
int parity = 0;
for ( int mask = 4; mask; mask >>= 1 )
{
for ( int bit = 1; bit <= 7; bit++ )
if ( bit & mask )
if ( input[7-bit] == '1' )
parity ^= mask;
}
printf( "%d\n", parity );
}

Resources