Converting Hexadecimal string to int - c

Write a C function, that accepts a null-terminated string, containing a hexadecimal string, and returns the integer value. You cannot call any C library function, except strlen() to code the function. The decimal string will only contain 0-4 ASCII characters from ‘0’ through ‘9’ and ‘A’ through ‘F’. No error handling is required. If the string is empty, then return a value of 0.
I've constantly tried fixing my errors, but once I fix them, new errors pop up, resulting in me being confused.
#include <stdlib.h> /*used for EXIT_SUCCESS */
#include <stdio.h> /*used for printf */
#include <string.h> /* used for strlen */
#include <stdbool.h> /* used for bool */
#include <math.h>
unsigned int hexStringTouint(const char str[], int length, int n[])
{
int i, j;
int intvalue = 0;
int digit;
for(i = (length-1), j = 0; i --, j++)
{
if(n[i]>='0' && n[i] <='9')
{
digit = n[i] - 0x30;
}
else if(n[i]>= 'A' && n[i] <= 'F')
{
switch(n[i])
{
case 'A': digit = 10; break;
case 'B': digit = 11; break;
case 'C': digit = 12; break;
case 'D': digit = 13; break;
case 'E': digit = 14; break;
case 'F': digit = 15; break;
}
}
intvalue += digit*pow(16,j);
}
printf("int value is %d\n", intvalue);
return 0;
}
int main(void)
{
int i, length, intvalue;
unsigned char n[] = "";
printf("Enter your hexadecimal string: ");
scanf("%c\n", n);
intvalue = 0;
length = strlen(n);
return EXIT_SUCCESS;
}
I am getting error messages saying
expected ';' in 'for' statement specifier
and how const char* converts between pointers and integers.

Much of OP's code is the right track, yet various coding errors exist.
Add test condition
// for(i = (length-1), j = 0; i --, j++)
// v
for(i = (length-1), j = 0; i >= 0; i --, j++)
cannot call any C library function, except strlen()
// intvalue += digit*pow(16,j);
intvalue += digit*(1u << (4*j));
Return the value
Requirement "... and returns the integer value"
//int intvalue = 0;
//...
//printf("int value is %d\n", intvalue);
//return 0;
unsigned intvalue = 0;
...
printf("integer value is %u\n", intvalue);
return intvalue;
Buffer too small
// unsigned char n[] = "";
// scanf("%c\n", n);
char n[100] = "";
scanf("%99s", n);
hexStringTouint()
Function not called in main().
Other issues exist
A simpler approach
unsigned hexStringTouint2(const char *str) {
unsigned value = 0;
while (*str) {
unsigned digit = hexCharTouint(*str); // tbd code
value = value*16 + digit;
str++;
}
return value;
}

Related

Mistake in custom implementation of printf

I'm trying to implement my own version of printf and I'm having trouble when I need to print an argument of the form %pd, where p is the number of characters to be printed.
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
void print(char *, ...);
char *convert(unsigned int, int);
char *to_lower(unsigned int, int);
unsigned int count_digits(unsigned int);
int main()
{
char str[12]="World";
char c='A';
int n = 5, x= 1011, y = 12, z = 5, t = 10;
print("Hello s c |%s| |%c| 5 |%d| 5 some random %X %x %b %o words\n", str, c, n, x, y, z, t);
print("%5d\n", y);
}
void print(char *format, ...)
{
int num, precision = 0, nDigits, i, temp;
char *num_deca;
va_list lst;
va_start(lst, format);
while(*format != '\0')
{
if(*format != '%')
{
putchar(*format);
format++;
continue;
}
format++;
if(isdigit(*format))
{
temp = atoi(format);
precision = precision*10+temp;
//precision = atoi(format);
format++;
continue;
}
// format++;
switch(*format)
{
case 'c':
putchar(va_arg(lst, int));
break;
case 'd':
num = (va_arg(lst, int));
//nDigits = count_digits(num);
if(num > 0)
{
num_deca = convert(num, 10);
nDigits = count_digits(num);
for(i = 0; i < (precision - nDigits); i++)
{
putchar(' ');
}
fputs(num_deca, stdout);
// fputs(convert(num,10), stdout);
}
else
{
num = -num;
putchar('-');
fputs(convert(num,10), stdout);
}
break;
case 's':
fputs(va_arg(lst, char *), stdout);
break;
case 'X':
num = va_arg(lst, int);
fputs(convert(num,16), stdout);
break;
case 'x':
num = va_arg(lst, int);
fputs(to_lower(num,16), stdout);
break;
case 'b':
num = va_arg(lst, int);
fputs(convert(num,2), stdout);
break;
case 'o':
num = va_arg(lst, int);
fputs(convert(num,8), stdout);
break;
}
format++;
}
va_end(lst);
}
char *convert(unsigned int num, int base)
{
static char Representation[]= "0123456789ABCDEF";
static char buffer[50];
char *ptr;
ptr = &buffer[49];
*ptr = '\0';
do
{
*--ptr = Representation[num%base];
num /= base;
}while(num != 0);
return(ptr);
}
char *to_lower(unsigned int num, int base)
{
static char Representation[]= "0123456789abcdef";
static char buffer[50];
char *ptr;
ptr = &buffer[49];
*ptr = '\0';
do
{
*--ptr = Representation[num%base];
num /= base;
}while(num != 0);
return(ptr);
}
unsigned int count_digits(unsigned int n)
{
unsigned int counter = 0;
while(n != 0)
{
n = n/10;
counter++;
}
return counter;
}
Output: Hello s c |World| |A| 5 |5| 5 some random 3F3 c 101 12 words
d
So, the basic cases are working fine, the only issue I'm encountering is on the second print. The number 12 with %5d% should be whitespacewhitespacewhitespace12 (since 12 only has 2 digits). I computed the number of digits of the argument and used a for loop that goes until the difference between the precision and the number of digits, but then the program doesn't consider d as being part of the format specifier anymore and just prints the letter 'd'. Any idea why?
The problem is that you print every character until you find a '%'. If you find a '%' you go to the next character and process it. However, if the next character is a digit, you modify precission and make a 'continue' to the start of the loop. When re-starting the loop, the next character (a 'd') is not a '%', so it just get printed as is. You should have a variable that tells you if you are still processing a sequence, or either don't go to the start of the loop before you end the processing of the full sequence ('%5d').

Program to Invert a hexadecimal number in C [duplicate]

This question already exists:
Invert hexadecimal number: C Program [closed]
Closed 2 years ago.
My Approach:
Step 1. Firstly I converted Hexadecimal number into decimal number. (Hexa to decimal logic)
Then I Invert decimal number's bits using ~ operator and unsigned char datatype variable.
Step 2. And then I convert that decimal number into Hexadecimal number. (decimal to hexa logic)
Hence i got inverted hexadecimal number.
Input and output are string of hexadecimal numbers.
#include <stdio.h>
#include<string.h>
#include<math.h>
int
main ()
{
long decimal, qu, rem;
int k, j = 0;
char hexa[100];
int p = 0;
int dig, temp;
unsigned char re = 0;
char hex[32] = "42"; //input
int len = strlen (hex);
len--;
for (int i = len; i >= 0; i--)
{
switch (hex[i])
{
case 'A':
dig = 10;
break;
case 'B':
dig = 11;
break;
case 'C':
dig = 12;
break;
case 'D':
dig = 13;
break;
case 'E':
dig = 14;
break;
case 'F':
dig = 15;
break;
default:
dig = hex[i] - 48;
break;
}
temp = temp + dig * pow (16, p);
p++;
re = temp;
re = ~re;
}
qu = re;
while (qu != 0)
{
rem = qu % 16;
if (rem < 10)
hexa[j++] = 48 + rem;
else
hexa[j++] = 55 + rem;
qu = qu / 16;
}
for (k = j; k >= 0; k--)
{
printf ("%c", hexa[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("Please enter some hex: ");
unsigned int hex;
// scan input as hex into an integer
scanf("%x", &hex);
// truncate the last byte into a char
unsigned char c = hex;
// invert it
c = ~c;
// print it back out as uppercase hex
printf("Inverted hex: %02X\n", c);
return 0;
}
Well this maybe enough. This essential doing the same steps what you described, but with less code.
#include <stdio.h>
#include <string.h>
int main()
{
char * hex = "42ABE3";
unsigned dec;
for(int i = 0; i < strlen(hex); i++) {
sscanf(hex + i, "%1X", &dec);
printf("%X", 15 - dec);
}
}
Output
BD541C
Note that this code did not check if sscanf was successfull, but you could add that if you need.

How to cast a string to a integer

I have a 40 digit hex number stored in a string, I have to store it inside a struct called Int40 that only contains a pointer to an int.
typedef struct Int40
{
// a dynamically allocated array to hold a 40
// digit integer, stored in reverse order
int *digits;
} Int40;
this is what I have tried
Int40 *parseString(char *str)
{
Int40 *value = malloc(sizeof(Int40) * MAX40);
for (int i = 0; i < MAX40; i++)
{
value[i] = (int)str[i];
}
return value;
}
int main()
{
Int40 *p;
p = parseString("0123456789abcdef0123456789abcdef01234567");
printf("-> %d\n", *p);
}
I know that an Int cant contain 40 digits thats why I tried to store each number from the string in an array of integers but my code doesnt seem to work.
Edit: Also the number contains letters because is a hex number, will I have to the get the ascii value of the hex number to be able to store it in the array of int, how do i do that?
You might do something like the following (note that I omit verification of the argument char* and also assume that hex characters are lowercase)
// with if statements:
Int40 *parseString(char *str)
{
Int40 *value = malloc(sizeof(Int40) * MAX40);
// save the digits array locally (same memory address as value)
int* digits = value->digits;
for (int i = 0; i < MAX40; i++)
{
char c = str[i];
// decimal digits case
if (c >= '0' && c <= '9') {
digits[i] = c - '0'; // subtract '0' to get the numberical value of c
} else { // hex case
digits[i] = (c - 'a') + 10; // subtract 'a' to get the numerical value of c as 0 + 10 for hex characters A - F
}
}
return value;
}
An alternative:
// with a switch statements:
Int40 *parseString(char *str)
{
Int40 *value = malloc(sizeof(Int40) * MAX40);
// save the digits array locally (same memory address as value)
int* digits = value->digits;
for (int i = 0; i < MAX40; i++)
{
char c = str[i];
switch (c) {
// hex 10 - 15
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
digits[i] = (c - 'a') + 10;
break;
// hex 0 - 9
default:
digits[i] = c - '0';
}
}
return value;
}
#include <stdio.h>
#include <stdlib.h>
typedef int* hex;
hex parseString(char *str)
{
hex value = (hex)malloc(sizeof(int)*40);
for (int i = 0; i < 40; i++)
{
value[i] = str[i];
}
return value;
}
int main()
{
hex p;
p = parseString("0123456789abcdef0123456789abcdef01234567");
printf("-> %d\n", p[0]);
}
...
#include <stdio.h>
#include <stdlib.h>
typedef struct Int40
{
int* hex;
}Int40;
Int40 parseString(char *str)
{
Int40 value;
value.hex = (int*)malloc(sizeof(int)*40);
for (int i = 0; i < 40; i++)
{
value.hex[i] = str[i];
}
return value;
}
int main()
{
Int40 p;
p = parseString("0123456789abcdef0123456789abcdef01234567");
printf("-> %d\n", p.hex[0]);
}

Merging two index into one in array in C

I have an unsigned char array which contains hex bytes like below:
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
I want to merge them so that it becomes:
array[0] = "FF"
array[1] = "E2"
array[2] = "AA"
array[3] = "CC"
array[0] = '\xFF';
array[1] = '\xE2';
array[2] = '\xAA';
array[3] = '\xCC';
I have tried using sprintf but then I do not know how to specify index number in it. Any help.?
So, you want to convert your string, made of hexadecimal characters, into an array of bytes, right? Know your data.
sprintf() will not help you, since it produces strings. Instead, you will need to extract the 'value' of each hexa character and use it to calculate the value of your bytes.
So, let's create a helper function to convert a hexadecimal character to its integer value (or -1 if it is invalid). We will use the characters' ASCII values and the fact that character ranges are contiguous in the ASCII table
int char2hexa(unsigned char c)
{
if(c >= '0' && c <= '9') {
return (c - '0'); /* will return 0-9 */
} else if(c >= 'A' && c <= 'F') {
return (c - 'A') + 10; /* will return 10-15 */
} else if(c >= 'a' && c <= 'f') {
return (c - 'a') + 10; /* will return 10-15 */
} else {
return -1;
}
}
Now a byte will be constructed from two hexa values by using one as the upper nibble (multiplied by 16 or shifted left by 4) and the other as a lower nibble, so let's have a function for that:
unsigned char hexvals2byte(int upper, int lower)
{
return (upper * 16 + lower);
}
and put the pieces together. I will assume that:
you know the length of your input data
the length is even (you need two characters per byte)
you want to put the result in the same array
Here comes.
#include <stdio.h>
#include <stdlib.h>
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
unsigned length = 8;
int upper, lower;
for(int i = 0; i < length; i+=2) {
upper = char2hexa(array[i]);
lower = char2hexa(array[i+1]);
if(upper < 0 || lower < 0) {
/* handle input data format error */
fprintf(stderr, "ERROR: Cannot decode hexa values '%c%c'\n", array[i], array[i+1]);
exit(EXIT_FAILURE);
}
array[i/2] = hexvals2byte(upper, lower);
}
So you need a result array of unsigned char result[128][3], then assign the part results, grouping 2 source elements into one result sub-element:
unsigned char result[128][3] = { 0 };
int i;
for (i = 0; i < 255; ++i)
{
result[i/2][i%2] = array[i];
}
The reason for size 3 is, that you need 2 characters and one zero-delimiter to form a string.
An easy way to convert a digit to number is to subtract '0' from it:
char digit = '3';
int number = digit - '0'; /* number = 3 */
This works only for digits (digit >= '0' && digit <= '9'), for hexadecimal digits ('A', 'B', etc.) you have to do a little more job:
unsigned char result[127];
int i;
unsigned char current;
unsigned char calc_diff(unsigned char digit) {
if(digit >= '0' && digit <= '9')
return '0';
else if(digit >= 'A' && digit <= 'F')
return 'A' - 10;
else if(digit >= 'a' && digit <= 'f')
return 'a' - 10;
else
return 0; // handle invalid digit
}
for(i = 0; i < 128; ++i) {
current = array[2 * i];
result[i] = (current - calc_diff(current)) << 4;
current = array[(2 * i) + 1];
result[i] |= current - calc_diff(current);
}
You want to convert characters to their hexadecimal value and combine them in pairs.
Here is a simple program to illustrate how you can do this:
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
/* this method is inefficient but works for all encodings */
static const char xdigits[] = "abcdef0123456789ABCDEF";
const char *p = memchr(xdigits, c, 22);
return p ? (p - xdigits + 10) & 15 : -1;
}
int main(void) {
unsigned char array[255];
while (scanf("%254s", array) == 1) {
int i, j, d, d2 = 0;
for (i = j = 0; array[i] != '\0'; i++) {
d = xdigit(array[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", array[i]);
break;
}
d2 = (d2 << 4) | d;
if (i & 1) {
array[j++] = (unsigned char)d2;
d2 = 0;
}
}
array[j] = '\0';
printf("converted array: %s\n", array);
}
return 0;
}
Here is a more elaborate version, with an separate conversion function and more explicit output:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'A': case 'a':
return 10;
case 'B': case 'b':
return 11;
case 'C': case 'c':
return 12;
case 'D': case 'd':
return 13;
case 'E': case 'e':
return 14;
case 'F': case 'f':
return 15;
default:
return -1;
}
}
int xconvert(unsigned char *dest, const unsigned char *src, int len) {
int i, j, d, d2 = 0;
for (i = j = 0; i < len; i++) {
d = xdigit(src[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", src[i]);
return -1;
}
d2 = (d2 << 4) | d;
if (i & 1) {
dest[j++] = (unsigned char)d2;
d2 = 0;
}
}
if (i & 1) {
printf("missing trailing digit\n");
return -1;
}
return j;
}
int main(void) {
unsigned char array[255];
int i, len, c;
while (scanf("%254s", array) == 1) {
len = xconvert(array, array, strlen((char *)array));
if (len >= 0) {
printf("converted array: \"");
for (i = 0; i < len; i++) {
c = array[i];
if (isprint(c)) {
putchar(c);
} else {
printf("\\x%02X", c);
}
}
printf("\"\n");
}
}
return 0;
}
my stab at it. Here you have to know the size of the array. in your case 255
//counters and array's
int first = 0;
int second = 0;
int count = 0;
char foo[8] = {'F', 'F', 'E', '2', 'A', 'A', 'C', 'C'};
//array half the size of the first one.
char *done[4];
//loop through first array
while (first <= 7)
{
//if its the first letter
if (second == 0)
{
//allocate enough mem to second arr
done[count] = (char *)malloc(sizeof(char *) * 3);
//assaign the first letter
done[count][0] = foo[first];
//indicate the next step for the second letter
second = 1;
}
//if its the second letter
else if (second == 1)
{
//assign second letter
done[count][1] = foo[first];
//null the string
done[count][2] = '\0';
//increase posistion index for the second arr
count++;
//indicate nexxt step is a the first letter of the next step
second = 0;
}
//increment the index for the first arr
first++;
}
Given that the data is in ASCII format and you want to merge it into a raw binary format, then:
for(size_t i=0; i<n; i++)
{
array[i] = to_int(array[i]);
}
where to_int() is your custom routine for converting from hexadecimal ASCII to integer. That is, if digit subtract with '0', else if upper-case letter subtract with 'A' and add 0xA.
Then after that, merge the items:
for(size_t i=0; i<n; i+=2)
{
array[i] = (unsigned int)array[i]<<4 | array[i+1];
}
I suppose you mix up an 8 bit value (e.g. 0x0F, which is 15 in decimal) with a character value like 'F' (which corresponds to 70 in ASCII format) with a string literal "FF" (which corresponds to a pointer to a sequence of the three character values {'F','F','\0'}.
From the context you present it seems that you mean 8 bit values, which are represented by data type unsigned char.
Given that, the code could look as follows:
unsigned char array[255] = { 0xF,0xE,0x2,0xA,0xA,0xC,0xC };
int target=0;
for (int i=0; i<254; i+=2) {
array[target] = (array[i] << 4) + array[i+1];
target++;
}
Maybe there are uncertain things but perhaps you want to do this.
#include <stdio.h>
int main(void){
unsigned char array[255] = {//or char -> hex byte
'\xF', '\xF', '\xE', '\x2',
'\xA', '\xA', '\xC', '\xC',
};
int len = 8;
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);//FFE2AACC
}
printf("\n");
}
When the data held first is a hex character
#include <stdio.h>
#include <ctype.h>
int main(void){
unsigned char array[255] = {
'F', 'F', 'E', '2',
'A', 'A', 'C', 'C',
};
int len = 8;
for(int i = 0, j = 0; i < len; i++){
if(isxdigit(array[i])){//maybe redundant
if(isdigit(array[i])){
array[i] -= '0';
} else {
array[i] -= isupper(array[i]) ? 'A' : 'a';
array[i] += 10;
}
} else {
fprintf(stderr, "invalid data %c\n", array[i]);
return -1;
}
}
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);
}
printf("\n");
}

how to check if the input is a number or not in C?

In the main function of C:
void main(int argc, char **argv)
{
// do something here
}
In the command line, we will type any number for example 1 or 2 as input, but it will be treated as char array for the parameter of argv, but how to make sure the input is a number, in case people typed hello or c?
Another way of doing it is by using isdigit function. Below is the code for it:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXINPUT 100
int main()
{
char input[MAXINPUT] = "";
int length,i;
scanf ("%s", input);
length = strlen (input);
for (i=0;i<length; i++)
if (!isdigit(input[i]))
{
printf ("Entered input is not a number\n");
exit(1);
}
printf ("Given input is a number\n");
}
You can use a function like strtol() which will convert a character array to a long.
It has a parameter which is a way to detect the first character that didn't convert properly. If this is anything other than the end of the string, then you have a problem.
See the following program for an example:
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[]) {
int i;
long val;
char *next;
// Process each argument given.
for (i = 1; i < argc; i++) {
// Get value with failure detection.
val = strtol (argv[i], &next, 10);
// Check for empty string and characters left after conversion.
if ((next == argv[i]) || (*next != '\0')) {
printf ("'%s' is not valid\n", argv[i]);
} else {
printf ("'%s' gives %ld\n", argv[i], val);
}
}
return 0;
}
Running this, you can see it in operation:
pax> testprog hello "" 42 12.2 77x
'hello' is not valid
'' is not valid
'42' gives 42
'12.2' is not valid
'77x' is not valid
Using scanf is very easy, this is an example :
if (scanf("%d", &val_a_tester) == 1) {
... // it's an integer
}
A self-made solution:
bool isNumeric(const char *str)
{
while(*str != '\0')
{
if(*str < '0' || *str > '9')
return false;
str++;
}
return true;
}
Note that this solution should not be used in production-code, because it has severe limitations. But I like it for understanding C-Strings and ASCII.
Using fairly simple code:
int i;
int value;
int n;
char ch;
/* Skip i==0 because that will be the program name */
for (i=1; i<argc; i++) {
n = sscanf(argv[i], "%d%c", &value, &ch);
if (n != 1) {
/* sscanf didn't find a number to convert, so it wasn't a number */
}
else {
/* It was */
}
}
I was struggling with this for awhile, so I thought I'd just add my two cents:
1) Create a separate function to check if an fgets input consists entirely of numbers:
int integerCheck(){
char myInput[4];
fgets(myInput, sizeof(myInput), stdin);
int counter = 0;
int i;
for (i=0; myInput[i]!= '\0'; i++){
if (isalpha(myInput[i]) != 0){
counter++;
if(counter > 0){
printf("Input error: Please try again. \n ");
return main();
}
}
}
return atoi(myInput);
}
The above starts a loop through every unit of an fgets input until the ending NULL value. If it comes across a letter or an operator, it adds "1" to the int "counter" which is initially set to 0. Once the counter becomes greater than 0, the nested if statement instructs the loop to print an error message & then restart the program. When the loops completes, if int 'counter' is still the value of 0, it returns the initially inputted integer to be used in the main function ...
2) the main function would be:
int main(void){
unsigned int numberOne;
unsigned int numberTwo;
numberOne = integerCheck();
numberTwo = integerCheck();
return numberOne*numberTwo;
}
Assuming both integers are inputted correctly, the example provided will yield the result of int "numberOne" multiplied by int "numberTwo". The program will repeat for however long it takes to get two properly inputted integers.
if (sscanf(command_level[2], "%f%c", &check_f, &check_c)!=1)
{
is_num=false;
}
else
{
is_num=true;
}
if(sscanf(command_level[2],"%f",&check_f) != 1)
{
is_num=false;
}
how about this?
This works for me
#include <string.h>
int isNumber(char *n) {
int i = strlen(n);
int isnum = (i>0);
while (i-- && isnum) {
if (!(n[i] >= '0' && n[i] <= '9')) {
isnum = 0;
}
}
return isnum;
}
e.g.:
printf("%i\n", isNumber("12")); // 1
printf("%i\n", isNumber("033")); // 1
printf("%i\n", isNumber("0")); // 1
printf("%i\n", isNumber("")); // 0
printf("%i\n", isNumber("aaa")); // 0
printf("%i\n", isNumber("\n")); // 0
printf("%i\n", isNumber("a0\n")); // 0
The C library function int isdigit(int c) checks if the passed character is a decimal digit character.
#include <stdio.h>
#include <ctype.h>
int main () {
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) ) {
printf("var1 = |%c| is a digit\n", var1 );
} else {
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) ) {
printf("var2 = |%c| is a digit\n", var2 );
} else {
printf("var2 = |%c| is not a digit\n", var2 );
}
return(0);
}
the result is :
var1 = |h| is not a digit
var2 = |2| is a digit
The sscanf() solution is better in terms of code lines. My answer here is a user-build function that does almost the same as sscanf(). Stores the converted number in a pointer and returns a value called "val". If val comes out as zero, then the input is in unsupported format, hence conversion failed. Hence, use the pointer value only when val is non-zero.
It works only if the input is in base-10 form.
#include <stdio.h>
#include <string.h>
int CONVERT_3(double* Amt){
char number[100];
// Input the Data
printf("\nPlease enter the amount (integer only)...");
fgets(number,sizeof(number),stdin);
// Detection-Conversion begins
int iters = strlen(number)-2;
int val = 1;
int pos;
double Amount = 0;
*Amt = 0;
for(int i = 0 ; i <= iters ; i++ ){
switch(i){
case 0:
if(number[i]=='+'){break;}
if(number[i]=='-'){val = 2; break;}
if(number[i]=='.'){val = val + 10; pos = 0; break;}
if(number[i]=='0'){Amount = 0; break;}
if(number[i]=='1'){Amount = 1; break;}
if(number[i]=='2'){Amount = 2; break;}
if(number[i]=='3'){Amount = 3; break;}
if(number[i]=='4'){Amount = 4; break;}
if(number[i]=='5'){Amount = 5; break;}
if(number[i]=='6'){Amount = 6; break;}
if(number[i]=='7'){Amount = 7; break;}
if(number[i]=='8'){Amount = 8; break;}
if(number[i]=='9'){Amount = 9; break;}
default:
switch(number[i]){
case '.':
val = val + 10;
pos = i;
break;
case '0':
Amount = (Amount)*10;
break;
case '1':
Amount = (Amount)*10 + 1;
break;
case '2':
Amount = (Amount)*10 + 2;
break;
case '3':
Amount = (Amount)*10 + 3;
break;
case '4':
Amount = (Amount)*10 + 4;
break;
case '5':
Amount = (Amount)*10 + 5;
break;
case '6':
Amount = (Amount)*10 + 6;
break;
case '7':
Amount = (Amount)*10 + 7;
break;
case '8':
Amount = (Amount)*10 + 8;
break;
case '9':
Amount = (Amount)*10 + 9;
break;
default:
val = 0;
}
}
if( (!val) | (val>20) ){val = 0; break;}// val == 0
}
if(val==1){*Amt = Amount;}
if(val==2){*Amt = 0 - Amount;}
if(val==11){
int exp = iters - pos;
long den = 1;
for( ; exp-- ; ){
den = den*10;
}
*Amt = Amount/den;
}
if(val==12){
int exp = iters - pos;
long den = 1;
for( ; exp-- ; ){
den = den*10;
}
*Amt = 0 - (Amount/den);
}
return val;
}
int main(void) {
double AM = 0;
int c = CONVERT_3(&AM);
printf("\n\n%d %lf\n",c,AM);
return(0);
}

Resources