Home > Net >  How to differentiate between ascii value and a number?
How to differentiate between ascii value and a number?

Time:09-17

I am asking if there is any way in C to differentiate between an ASCII value and a number, for example 'A' and 65 both have value of 65, but how to differentiate between them?

Assume we want to sum up two numbers, so sum(10,65) should return 75, but sum(10,'A') should return 0. Also, keep in mind that the arguments of sum() should have the same type, which is double.

CodePudding user response:

Use overloaded functions. It is quite short with your conditions (returning 0 for all argument types that are not double):

double sum(double a, double b) { return a   b; }

template <typename A, typename B>
double sum(A a, B b) { return 0; }

CodePudding user response:

In C 17 and later, you can make sum() be a template function, and then use if constexpr to let sum() make decisions based on the types of parameters it is actually passed, eg:

#include <iostream>
#include <type_traits>

template <typename T, typename... Ts>
inline constexpr bool is_any_v = (... || std::is_same_v<T, Ts>);

template <typename T>
inline constexpr bool is_char_v = is_any_v<T, char, wchar_t, char16_t, char32_t>;

template<typename T>
inline constexpr bool is_arithmetic_not_char = std::is_arithmetic_v<T> && !is_char_v<T>;

template<typename A, typename B>
double sum(A a, B b) {
    if constexpr (is_arithmetic_not_char<A> && is_arithmetic_not_char<B>)
        return a   b;
    else
        return 0;
}

int main()
{
    std::cout << sum(10, 65) << std::endl; // 75
    std::cout << sum(10, 'A') << std::endl; // 0
    return 0;
}

Online Demo

The std::is_arithmetic trait is true only for integral types and floating point types, and false for all other types. The problem is that character types, like char, are also integral types. So, this code allows sum() to actually calculate a result only if called with arithmetic types that are not also character types, otherwise it will return 0 for everything else.

However, your question is tagged C 11 and C 14, and in those versions, if constexpr is not available (same with fold expressions), but you can use std::enable_if instead to accomplish something similar using SFINAE, eg:

#include <iostream>
#include <type_traits>

template<typename T>
constexpr bool is_char_v = std::is_same<T,char>::value || std::is_same<T,wchar_t>::value || std::is_same<T,char16_t>::value || std::is_same<T,char32_t>::value;

template<typename T>
constexpr bool is_arithmetic_not_char = std::is_arithmetic<T>::value && !is_char_v<T>;

template<typename A, typename B, typename std::enable_if<is_arithmetic_not_char<A> && is_arithmetic_not_char<B>, int>::type = 0>
double sum(A a, B b) {
    return a   b;
}

template<typename A, typename B, typename std::enable_if<!(is_arithmetic_not_char<A> && is_arithmetic_not_char<B>), int>::type = 0>
double sum(A, B) {
    return 0;
}

int main()
{
    std::cout << sum(10, 65) << std::endl; // 75
    std::cout << sum(10, 'A') << std::endl; // 0
    return 0
}

Online Demo

CodePudding user response:

Would the isdigit() function work for you?

char value = 'A'; 
if (isdigit(value))
   sum(10, value); 
else
   sum(0, 0);
  • Related