Hexadecimal number comparison? - c

I'm a new to C language and a bit confused about how hexadecimal, decimal numbers work. I am trying to work with maximum of 4 bytes, so 0xFFFFFFFF. I basically want the program to give an alert if any number is entered with 9 digits or higher. I have written a code as below but it still lets me input numbers bigger than 0xFFFFFFFF. What am I doing wrong? Thanks in advance!
int main()
{
uint32_t rgba;
printf("Enter rgba value: ");
scanf("%x", &rgba);
if (rgba > 0xFFFFFFFF){
printf("Maximum number of 8 digits!\n");
}
else{
rgba_values(rgba);
}
return 0;
}

As #Jongware commented, "You cannot check for a number larger than it is possible to store."
To detect if user input is outside the range of uint32_t rgba, code needs to understand that the user input has or will exceed that range.
Method 1: Use larger integer type: This method will detect "100000000" as too large an input, but will have trouble with numbers larger than "FFFFFFFFFFFFFFFF".
unsigned long long UserInput;
uint32_t rgba;
printf("Enter rgba value: ");
if (scanf("%llx", &UserInput) != 1) {
puts("EOF or Scan Failure");
return 1;
}
if (UserInput > 0xFFFFFFFFu) {
puts("Range error");
return 1;
}
rgba = UserInput;
rgba_values(rgba);
Method 2: Use fgets()/strtoul(). The following will work for input up to 99 char long (which includes the '\n').
uint32_t rgba;
char *buf[100];
printf("Enter rgba value: ");
if(fgets(buf, sizeof buf, stdin) == NULL) {
puts("EOF");
return 1;
}
char *endptr = 0;
errno = 0;
unsigned long ul = strtoul(buf, &endptr, 16);
if (buf == endptr) {
puts("No conversion");
return 1;
}
if (errno || ul > 0xFFFFFFFFu) {
puts("value out of range");
return 1;
}
rgba = (uint32_t) ul;
rgba_values(rgba);
Other methods include counting the number of hexadecimal characters or converting user input 1 char at a time.

if (rgba > 0xFFFFFFFF)
rgba is a 32-bit unsigned integer value, the condition above is always false. A 32-bit unsigned integer value is always <= 0xFFFFFFFF.

Check the return value of scanf: it returns 1 if and only if the input is a valid hexadecimal number without overflow. Note that this will only fit your purpose if the int is exactly 32 bits on your platform.

What you could do is store the user-input into a char* first:
char rgba_str[20]; // 20 is an arbitrary larger buffer size
printf("Enter rgba value: ");
scanf("%s", &rgba_str);
Then check and see if the length of the string is greater than 9 digits:
if ( strlen( rgba_str ) > 8 )
// Error
If not, turn rgba_str into a hexadecimal integer:
else
rgba = strtoul(rgba_str, NULL, 16);

Related

How to limits value user input < INT_MAX in C

#include <stdio.h>
#include <stdlib.h>
#include<limits.h>
int getInt() {
int n, check;
char ch;
do {
fflush(stdin);
printf("Enter positive integer n = ");
check = scanf("%d%c", &n, &ch);
if ((check == 2)&&(ch == '\n')) {
if (n > INT_MAX) {
printf("Invalid number\n");
} else if (n < 0) {
printf("n must > 0");
} else {
break;
}
} else printf("Invalid number\n");
} while (1);
return n;
}
int main(int argc, char** argv) {
int n;
n = getInt();
}
My code accepts user input number in range 0 to INT_MAX.
When I input -1, program displays "n must > 0".
But when I input '77777777777777777777777777777777' (> INT_MAX) program still displays "n must > 0", and not 'Invalid number'.
With out of range input in scanf("%d%c", &n, &ch);, the behavior is undefined.
Instead read a line of input with fgets(), then quality using strtol()
for (;;) {
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) {
printf("No more input\n");
return -1;
}
errno = 0;
char *endptr;
long val = strtol(buf, &endptr, 0);
// No numeric conversion done at all?
// Numeric input outside long range?
// Junk after the numeric text?
if (buf == endptr || errno == ERANGE || *endptr != '\n') {
printf("Invalid number\n");
continue;
}
// Outside int range?
if (val < INT_MIN || val > INT_MAX) {
printf("Invalid number\n");
continue;
}
if (val < 0) {
printf("n must > 0");
continue;
}
n = (int) val;
}
I'd recommend a re-usable int get_int(int *val) helper function.
First you need to understand how variables stores data.
In 64 bits architeture, the int type have 4 bytes (either the C long type, regardless architeture), so can store the following values:
00000000 00000000 00000000 00000000 = 0 (decimal value)
01111111 11111111 11111111 11111111 = 2,147,483,647 (decimal value)
11111111 11111111 11111111 11111111 = 4,294,967,294 (unsigned decimal value)
11111111 11111111 11111111 11111111 = -1 (signed decimal value)
Note that the integer types can use the Most Significant Bit (MSB) to represent signal (0 to positive, 1 to negative) using a modular aritmetic.
For more details about integer signal: https://en.wikipedia.org/wiki/Two%27s_complement
So, to store decimal data higher than INT_MAX, you need more bytes than you have using int type. A good way, compatible with 64 bits architeture, is using long long type.
Long long type uses 8 bytes, so can stores value higher than INT_MAX.
You will have to declare:
long long n;
And use scanf() like this:
scanf("%lld%c", &n, &ch);
Your fflush(stdin) have to be after the scanf(), because if your aplication break the loop after the scanf() and before have reached the fflush() instruction you may have problem in further input handling. Like this:
check = scanf("%lld%c", &n, &ch);
fflush(stdin);
However, some developers disapprove use fflush() in stdin, so this is an alternative (a bit more complex) using getch() accepting only numbers and converting char* to long long using strtoll():
char c = 0;
char* input_number = malloc(32);
int accepted_chars = 0;
memset(input_number, 0, 32);
while(c != '\r'){ //loop until user press ENTER
c = getch();
//receive numbers keys pressed
if(c >= '0' && c <= '9'){
*(input_number + accepted_chars) = c;
accepted_chars ++;
printf("%c", c);
}
//receive backspace key pressed
if(c == 8){
if(accepted_chars > 0){ //don't do nothing if there is nothing to clear
accepted_chars --;
*(input_number + accepted_chars) = 0;
printf("\b");
printf(" ");
printf("\b");
}
}
}
printf("\n");
char* endptr;
n = strtoll(input_number, &endptr, 10); //convert string in base 10 (decimal) long long type
Just checking
int x;
...
if (x > INT_MAX) { ...
is something that will never work. If an int value cannot have values above INT_MAX then it is impossible that you can ever get x stored a value higher than that. So that if will become always false and the compiler will probably eliminate all the code you put inside that if's then block.
Normal reading routines like scanf() actually limit the input to a value in the range of allowable values.
But if you want to read and build the number yourself, you need to ancitipate the possibility, and use better triggers to stop.
For example, checking that the number is above (INT_MAX - 9) / 10 will tell you that if you try to add another digit to it, you'll run the risk of overflowing the integer, when you add the digit. You can simply stop there and don't continue reading, but if you want to read one more digit (who knows, it could be a 0 and that doesn't hurt, you'll have to check for something like
int digit;
int the_integer = 0;
while ( (digit = fgetchar(stdin)) != EOF
&& isdigit(digit)
&& the_integer <= (INT_MAX - (digit - '0')))
{
the_integer *= 10;
the_integer += digit;
} /* while */
if (digit != EOF && isdigit(digit)) {
/* x > (INT_MAX - (digit - '0')) */
/* this is necessary, as if you don't do it, you'll lose
* the next character to read. */
unput(digit, stdin);
}
This way you'll check the number x before multiplying it by 10 and adding the digit - '0' value.
As pointed out in the comments section, there is no point in testing if n > INT_MAX, as n is of type int and therefore by definition unable to represent any value larger than INT_MAX.
A simple, flexible way of checking the size of a number provided as user input would be to read it in as a string and count the number of digits by using the function strlen and possibly also isdigit to count the actual digits.
However, when dealing with potentially large numerical values as user input, it is usually better to first read this input into a data type that is larger than int and do your range checks with this larger data type. After you are satisfied that the number is in the desired range, you can convert it to the smaller int data type. Although the ISO C standard does not guarantee that a long long is larger than an int, this is a reasonable assumption and it is the case on all compilers that I am aware of. However, on some platforms (including 64-bit Windows), the data type long is the same size as int, so a long cannot be reliably used for this on all platforms.
Probably the easiest solution to your problem would be to use the function strtol or strtoll. Using these functions has the advantage that you don't need a larger data type and it explicitly tells you if a number is out of range, by setting errno to ERANGE. However, these functions only support the data types long and long long, but not int. Therefore, if you want to use int, you will have to do your range checks manually before you convert it.

How to make this code scanf a sequence of integers until I enter negative integer? I thaught %u won't take negative integers

I want that while loop ends when I enter number that's not unsigned
(lower than zero), but that just not happen until I type some symbol
on my keyboard (letter etc.) and then debugging stops. Can anyone help
me, please?
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define ALLOC_CHECK(p) if (!(p)) puts("Neuspesna alokacija"), exit(1)
bool is_palindrome(unsigned x)
{
unsigned i, j, n = 8 * sizeof x; // Broj bita unsigned x
for (i = 1 << n-1, j = 1; i > j; i >>= 1, j <<= 1)
if (!(x & i) != !(x & j)) // Proverava da li su biti logicki razliciti
return false;
return true;
}
int main(void)
{
unsigned size = 10, n = 0, i;
unsigned *a = malloc(size * sizeof(*a));
ALLOC_CHECK(a);
puts("Enter a sequence of integers:");
while (scanf("%u", &a[n++]))
if (n == size) {
size *= 2;
a = realloc(a, size * sizeof(*a));
ALLOC_CHECK(a);
}
// Moze i da se skrati na pravu duzinu sa a = realloc(a, n * sizeof(*a));
puts("Binary palindromes are:");
for (i = 0; i < n; i++)
if (is_palindrome(a[i]))
printf("%u ", a[i]);
free(a);
}
I want that while loop ends when I enter number that's not unsigned (lower than zero).
Think of input as text that needs testing.
// input examples
"-12345678901234567890" should stop the loop
"-1" should stop the loop
"123" should be read successfully as an `unsigned`
" +123" should be read successfully as an `unsigned`
"12345678901234567890" is outside `unsigned` range and results are TBD
"abc" is not `unsigned`, so should stop loop.
"" is not `unsigned`, so should stop loop.
" 123 xyz" is not `unsigned`, so should stop loop.
etc.
Using fgets() is more robust, yet let us try a scanf() solution.
I thought %u won't take negative integers
scanf("%u",... will take input like "-123" and convert that to an unsigned. So code is needed to detect a -
Following will not detect overflow nor white-space only lines nor consume text after a -.
// consume leading white space, look for `-` (various approaches)
int n = 0;
scanf(" -%n", &n);
if (n > 0) exit_loop(); // `-` found
unsigned x;
if (scanf("%u", &x) != 1) exit_loop(); // non numeric input
// Success, use `x`
...
In an ugly while loop that use " %1[-]" to look for a -
char minus[2];
// while a search for `-` failed and `unsigned` succeeded
while (scanf(" %1[-]", minus) != 1 && scanf("%u", &x) == 1) {
...
}
As pointed out by #AnT, a negative value is a valid input for scanf("%u" ...
I suggest to use a signed type long in conjunction with fgets and strtol in order to catch negative values:
puts("Enter a sequence of integers:");
char str[32], *ptr;
long val;
while (fgets(str, sizeof str, stdin)) {
val = strtol(str, &ptr, 10);
if ((*ptr == '\n') && (val >= 0)) {
a[n++] = strtoul(str, NULL, 10);
} else break;
if (n == size) {
size *= 2;
a = realloc(a, size * sizeof(*a));
ALLOC_CHECK(a);
}
}
Negative numbers are considered valid input for %u.
This is what C90 says about %u:
Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of the strtoul function with the value 10 for the base argument. The corresponding argument shall be a pointer to unsigned integer.
And it says this about strtoul():
the expected form of the subject sequence is a sequence of letters and digits representing an integer with the radix specified by base, optionally preceded by a plus or minus sign, but not including an integer suffix.
...
If the subject sequence begins with a minus sign, the value resulting from the conversion is negated.
Instead you should read the input as an int and then check whether it is positive or negative. i.e:
scanf("%d", &a[n]);
if(a[n++] >= 0)
And yes, that reduces the range of positive number you can input to half but that's the way to go about it.
Other than that you can get the input as char and then parse them yourself which isn't that hard to be honest. something like
unsigned int num = 0;
while(isdigit(c = getchar()))
num = num * 10 + c;
as a very simple solution. of course you can check for an optional + at the beginning and probably accept other bases and much more but this was just a simple code to show you the idea.
I want that while loop ends when I enter number that's not unsigned (lower than zero).
scanf("%u", ...) will read text "-123" in and successfully convert that to an unsigned.
A fairly safe assumption is UINT_MAX <= INTMAX_MAX. In other words, the widest signed integer covers the unsigned range. On rare machines, this is not true - as allowed by C.
Use scanf() (which lacks OF protection) or fgets()/strtoimax()
#include <limits.h>
#include <stdint.h>
#if UINT_MAX > INTMAX_MAX
#error range issue
#endif
intmax_t big_input;
while (scanf("%jd", &big_input) == 1 && (big_input >= 0)) {
if (big_input > UINT_MAX) TBD_Code();
a[n++] = (unsigned) big_input;
// do stuff
}
char buff[20];
while (1)
{
do
{
printf("Enter number: ");
fgets(buff, 20, stdin);
} while (!sscanf(buff, "%u", &a_a));
if(a[n] == (0UL - 1UL)) break;
if (++n == size) {
size *= 2;
a = realloc(a, size * sizeof(*a));
ALLOC_CHECK(a);
}
}

Arithmetic overflow when using atoi() on argv[1] in C

I am using atoi(argv[1]) Here is a snippet of my code
void main(int argc, char* argv[])
{
int evenOrOdd = 0;
int inputtedNum = 0;
pid_t pid;
int i;
char buf[BUF_SIZE];
if (argc != 2)//make sure user has input correctly entered
{
printf("Please use input: ./a.out #\n");
}
else
{
inputtedNum = atoi(argv[1]);
if(inputtedNum < 0) //make sure number is positive
{
printf("Please use a positive number.\n");
return;
}
}
// ...
}
The code goes on and whatnot, but when entering some numbers, it will sometimes believe they're negative. If I enter 123456789 it will have no problem and run the program correctly. If I enter 12345678910 It will think the number is a negative number. Am I running into some buffer error here to where the negative flag flops? I'm not quite certain how to fix it.
Any and all help is appreciated!
int is a relatively narrow integer type, and also it is a signed type. Use unsigned long for inputtedNum and strtoul(argv[1], 0, 0) to parse the number.
On most compilers, the largest non-negative integer type supported in C is a 64-bit unsigned integer.
12345678910 cannot be stored in the int type that you are using, even if it was unsigned long.
You can solve this issue by "dividing" the input string in argv[1] into two strings, when it is longer than 8 digits, use atoi on each string, and combine the results into an unsigned long long variable.
This will extend your positive range from approximately 4 billion, to the largest 16-decimal-digit number.
From main, call readNum(argv[1]):
unsigned long long readNum(const char* input)
{
int length = strlen(input);
if (length <= 8)
{
return atoi(input);
}
else if (length <= 16)
{
char str1[8+1] = {0};
char str2[8+1] = {0};
memcpy(str1,input,8);
memcpy(str2,input+8,length-8);
return 100000000ULL*atoi(str1)+atoi(str2);
}
return 10000000000000000ULL; // Invalid input
}
Keep in mind that in order to print an unsigned long long, you need to use printf with %llu.

converting string to hex

I have a string that has 0111111100000000000000000000101
I wanted to convert this to hex, so I used the code below
int assembledHex;
sscanf(buffer, "%x", &assembledHex);
printf("this is the assembled hex %x\n",assembledHex);
but when I print it, it gives me 101. I thought sscanf can convert to hex from a string, what am I doing wrong and how can I fix it. The result I want is 0x3F800005
This is not checked or anything, and also quite slow, but it's a quick start:
unsigned int bin_to_int(const char *s) {
int i;
unsigned int result;
result = 0;
if (s[0] == '1') result++;
for (i = 1; i < strlen(s); i++) {
result <<= 1;
if (s[i] == '1') {
result++;
}
}
return result;
}
Your sscanf is reading the string as HEX, but the string is written in binary. You get "101" because int can only store the first 8 digits - each digit is 4 bits, so two digits=8 bits=1 byte, and 8 digits are 4 bytes, which is the size of int. So you actually store "00000101", buy printf does not print the leading zeroes so you get "101".

Check if input is integer type in C

The catch is that I cannot use atoi or any other function like that (I'm pretty sure we're supposed to rely on mathematical operations).
int num;
scanf("%d",&num);
if(/* num is not integer */) {
printf("enter integer");
return;
}
I've tried:
(num*2)/2 == num
num%1==0
if(scanf("%d",&num)!=1)
but none of these worked.
Any ideas?
num will always contain an integer because it's an int. The real problem with your code is that you don't check the scanf return value. scanf returns the number of successfully read items, so in this case it must return 1 for valid values. If not, an invalid integer value was entered and the num variable did probably not get changed (i.e. still has an arbitrary value because you didn't initialize it).
As of your comment, you only want to allow the user to enter an integer followed by the enter key. Unfortunately, this can't be simply achieved by scanf("%d\n"), but here's a trick to do it:
int num;
char term;
if(scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
You need to read your input as a string first, then parse the string to see if it contains valid numeric characters. If it does then you can convert it to an integer.
char s[MAX_LINE];
valid = FALSE;
fgets(s, sizeof(s), stdin);
len = strlen(s);
while (len > 0 && isspace(s[len - 1]))
len--; // strip trailing newline or other white space
if (len > 0)
{
valid = TRUE;
for (i = 0; i < len; ++i)
{
if (!isdigit(s[i]))
{
valid = FALSE;
break;
}
}
}
There are several problems with using scanf with the %d conversion specifier to do this:
If the input string starts with a valid integer (such as "12abc"), then the "12" will be read from the input stream and converted and assigned to num, and scanf will return 1, so you'll indicate success when you (probably) shouldn't;
If the input string doesn't start with a digit, then scanf will not read any characters from the input stream, num will not be changed, and the return value will be 0;
You don't specify if you need to handle non-decimal formats, but this won't work if you have to handle integer values in octal or hexadecimal formats (0x1a). The %i conversion specifier handles decimal, octal, and hexadecimal formats, but you still have the first two problems.
First of all, you'll need to read the input as a string (preferably using fgets). If you aren't allowed to use atoi, you probably aren't allowed to use strtol either. So you'll need to examine each character in the string. The safe way to check for digit values is to use the isdigit library function (there are also the isodigit and isxdigit functions for checking octal and hexadecimal digits, respectively), such as
while (*input && isdigit(*input))
input++;
(if you're not even allowed to use isdigit, isodigit, or isxdigit, then slap your teacher/professor for making the assignment harder than it really needs to be).
If you need to be able to handle octal or hex formats, then it gets a little more complicated. The C convention is for octal formats to have a leading 0 digit and for hex formats to have a leading 0x. So, if the first non-whitespace character is a 0, you have to check the next character before you can know which non-decimal format to use.
The basic outline is
If the first non-whitespace character is not a '-', '+', '0', or non-zero decimal digit, then this is not a valid integer string;
If the first non-whitespace character is '-', then this is a negative value, otherwise we assume a positive value;
If the first character is '+', then this is a positive value;
If the first non-whitespace and non-sign character is a non-zero decimal digit, then the input is in decimal format, and you will use isdigit to check the remaining characters;
If the first non-whitespace and non-sign character is a '0', then the input is in either octal or hexadecimal format;
If the first non-whitespace and non-sign character was a '0' and the next character is a digit from '0' to '7', then the input is in octal format, and you will use isodigit to check the remaining characters;
If the first non-whitespace and non-sign character was a 0 and the second character is x or X, then the input is in hexadecimal format and you will use isxdigit to check the remaining characters;
If any of the remaining characters do not satisfy the check function specified above, then this is not a valid integer string.
First ask yourself how you would ever expect this code to NOT return an integer:
int num;
scanf("%d",&num);
You specified the variable as type integer, then you scanf, but only for an integer (%d).
What else could it possibly contain at this point?
If anyone else comes up with this question, i've written a program, that keeps asking to input a number, if user's input is not integer, and finishes when an integer number is accepted
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
bool digit_check(char key[])
{
for(int i = 0; i < strlen(key); i++)
{
if(isdigit(key[i])==0)
{
return false;
}
}
return true;
}
void main()
{
char stroka[10];
do{
printf("Input a number: ");
scanf("%s",stroka);}
while (!digit_check(stroka));
printf("Number is accepted, input finished!\n");
system("pause");
}
I looked over everyone's input above, which was very useful, and made a function which was appropriate for my own application. The function is really only evaluating that the user's input is not a "0", but it was good enough for my purpose. Hope this helps!
#include<stdio.h>
int iFunctErrorCheck(int iLowerBound, int iUpperBound){
int iUserInput=0;
while (iUserInput==0){
scanf("%i", &iUserInput);
if (iUserInput==0){
printf("Please enter an integer (%i-%i).\n", iLowerBound, iUpperBound);
getchar();
}
if ((iUserInput!=0) && (iUserInput<iLowerBound || iUserInput>iUpperBound)){
printf("Please make a valid selection (%i-%i).\n", iLowerBound, iUpperBound);
iUserInput=0;
}
}
return iUserInput;
}
Try this...
#include <stdio.h>
int main (void)
{
float a;
int q;
printf("\nInsert number\t");
scanf("%f",&a);
q=(int)a;
++q;
if((q - a) != 1)
printf("\nThe number is not an integer\n\n");
else
printf("\nThe number is an integer\n\n");
return 0;
}
This is a more user-friendly one I guess :
#include<stdio.h>
/* This program checks if the entered input is an integer
* or provides an option for the user to re-enter.
*/
int getint()
{
int x;
char c;
printf("\nEnter an integer (say -1 or 26 or so ): ");
while( scanf("%d",&x) != 1 )
{
c=getchar();
printf("You have entered ");
putchar(c);
printf(" in the input which is not an integer");
while ( getchar() != '\n' )
; //wasting the buffer till the next new line
printf("\nEnter an integer (say -1 or 26 or so ): ");
}
return x;
}
int main(void)
{
int x;
x=getint();
printf("Main Function =>\n");
printf("Integer : %d\n",x);
return 0;
}
I developed this logic using gets and away from scanf hassle:
void readValidateInput() {
char str[10] = { '\0' };
readStdin: fgets(str, 10, stdin);
//printf("fgets is returning %s\n", str);
int numerical = 1;
int i = 0;
for (i = 0; i < 10; i++) {
//printf("Digit at str[%d] is %c\n", i, str[i]);
//printf("numerical = %d\n", numerical);
if (isdigit(str[i]) == 0) {
if (str[i] == '\n')break;
numerical = 0;
//printf("numerical changed= %d\n", numerical);
break;
}
}
if (!numerical) {
printf("This is not a valid number of tasks, you need to enter at least 1 task\n");
goto readStdin;
}
else if (str[i] == '\n') {
str[i] = '\0';
numOfTasks = atoi(str);
//printf("Captured Number of tasks from stdin is %d\n", numOfTasks);
}
}
printf("type a number ");
int converted = scanf("%d", &a);
printf("\n");
if( converted == 0)
{
printf("enter integer");
system("PAUSE \n");
return 0;
}
scanf() returns the number of format specifiers that match, so will return zero if the text entered cannot be interpreted as a decimal integer
The way I worked around this question was using cs50.h library. So, the header goes:
#include <cs50.h>
There you have get_int function and you simply use it for variable initiation:
int a = get_int("Your number is: ");
If a user inputs anything but integer, output repeats the line "Your number is: "; and so on until the integer is being written.
I've been searching for a simpler solution using only loops and if statements, and this is what I came up with. The program also works with negative integers and correctly rejects any mixed inputs that may contain both integers and other characters.
#include <stdio.h>
#include <stdlib.h> // Used for atoi() function
#include <string.h> // Used for strlen() function
#define TRUE 1
#define FALSE 0
int main(void)
{
char n[10]; // Limits characters to the equivalent of the 32 bits integers limit (10 digits)
int intTest;
printf("Give me an int: ");
do
{
scanf(" %s", n);
intTest = TRUE; // Sets the default for the integer test variable to TRUE
int i = 0, l = strlen(n);
if (n[0] == '-') // Tests for the negative sign to correctly handle negative integer values
i++;
while (i < l)
{
if (n[i] < '0' || n[i] > '9') // Tests the string characters for non-integer values
{
intTest = FALSE; // Changes intTest variable from TRUE to FALSE and breaks the loop early
break;
}
i++;
}
if (intTest == TRUE)
printf("%i\n", atoi(n)); // Converts the string to an integer and prints the integer value
else
printf("Retry: "); // Prints "Retry:" if tested FALSE
}
while (intTest == FALSE); // Continues to ask the user to input a valid integer value
return 0;
}
Just check is your number has any difference with float version of it, or not.
float num;
scanf("%f",&num);
if(num != (int)num) {
printf("it's not an integer");
return;
}
This method works for everything (integers and even doubles) except zero (it calls it invalid):
The while loop is just for the repetitive user input. Basically it checks if the integer x/x = 1. If it does (as it would with a number), its an integer/double. If it doesn't, it obviously it isn't. Zero fails the test though.
#include <stdio.h>
#include <math.h>
void main () {
double x;
int notDouble;
int true = 1;
while(true) {
printf("Input an integer: \n");
scanf("%lf", &x);
if (x/x != 1) {
notDouble = 1;
fflush(stdin);
}
if (notDouble != 1) {
printf("Input is valid\n");
}
else {
printf("Input is invalid\n");
}
notDouble = 0;
}
}
I was having the same problem, finally figured out what to do:
#include <stdio.h>
#include <conio.h>
int main ()
{
int x;
float check;
reprocess:
printf ("enter a integer number:");
scanf ("%f", &check);
x=check;
if (x==check)
printf("\nYour number is %d", x);
else
{
printf("\nThis is not an integer number, please insert an integer!\n\n");
goto reprocess;
}
_getch();
return 0;
}
I found a way to check whether the input given is an integer or not using atoi() function .
Read the input as a string, and use atoi() function to convert the string in to an integer.
atoi() function returns the integer number if the input string contains integer, else it will return 0. You can check the return value of the atoi() function to know whether the input given is an integer or not.
There are lot more functions to convert a string into long, double etc., Check the standard library "stdlib.h" for more.
Note : It works only for non-zero numbers.
#include<stdio.h>
#include<stdlib.h>
int main() {
char *string;
int number;
printf("Enter a number :");
string = scanf("%s", string);
number = atoi(string);
if(number != 0)
printf("The number is %d\n", number);
else
printf("Not a number !!!\n");
return 0;
}

Resources