Search code examples
ccharcomparisonsingle-quotes

Comparing Char with == and single quote gives warning


I am writing a program to calculate cosines and I should read the user input for angles given in degree (°) or radians (r). If the angle were to be given in degrees, it should be converted into radians (hence I used the if-else statement). However, when I compare char with == and single quote I get the following warning:

warning: multi-character character constant [-Wmultichar]
if((unit != '°') && (unit != 'r'))

This is my full code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

// Prototype
void calc_cos(double, char);

int main (void)
{
    double angle;
    char unit;
    printf("PLease give an angle and its unit in degrees (°) or radians (r) for cosinus calculation\n");
    if((unit != '°') && (unit != 'r'))
    {
        printf("ERROR. Unit is not in '°' or 'r'. Aborting...\n");
        return 0;
    }
    else
    {
    scanf("%lf %c", &angle, &unit);
    calc_cos(angle, unit);
    }
    return 0;
}

void calc_cos(double angle, char unit)
{
    double results=0;
    if(unit == '°')
    {
        angle = angle*M_PI/180;
    }
    else if(unit == 'r')
    {
        angle = angle;
    }
    results = cos(angle);
    printf("cos(%lf rad) = %lf\n", angle, results);
}

Solution

  • As others have indicated in the comments, the degree (°) character is not encoded as a single byte in the ASCII system; rather, it is interpreted by the compiler as a sequence of (probably) two bytes.

    There are various ways around this. One would be to use the wchar_t type for your unit variable, and the corresponding wide literals for the comparisons (L'°' and L'r', in place of '°' and 'r'); however, this would require changing (at least) your scanf call to use the %lc format specifier, but you would almost certainly be better of, in that case, using the wprintf and wscanf "wide-character" versions of the standard I/O functions.

    However, even with such changes, you are likely to encounter problems reading the ° character in a console application, as there are numerous different encoding systems that can be used. So, in my opinion, you would be better off using a simple letter d to specify units of degrees.

    Also, even with any of these fixes, there are some other issues in your code. The most notable is that you are testing the unit variable before it has been given. Code with this corrected, plus a few other suggested improvements (and using the d for degrees) is shown below:

    #include <stdio.h>
    #include <stdlib.h>
    #define _USE_MATH_DEFINES /// Many compilers require this to give the "M_PI" definition
    #include <math.h>
    
    // Prototype
    void calc_cos(double, char);
    
    int main(void)
    {
        double angle;
        char unit;
        printf("Please give an angle and its unit in degrees (d) or radians (r) for cosinus calculation\n");
        scanf("%lf %c", &angle, &unit); /// MUST read "unit" BEFORE testing it!
        if ((unit != 'd') && (unit != 'r')) {
            printf("ERROR. Unit is not in 'd' or 'r'. Aborting...\n");
            return 0;
        }
        calc_cos(angle, unit);
        return 0;
    }
    
    void calc_cos(double angle, char unit)
    {
        double results = 0;
        if (unit == 'd') {
            angle = angle * M_PI / 180;
        }
    //  else if (unit == 'r') { /// This block is unnecessary
    //      angle = angle;
    //  }
        results = cos(angle);
        printf("cos(%lf rad) = %lf\n", angle, results);
    }
    

    Please feel free to ask for any further clarification and/or explanation.