将 Char 与 == 和单引号进行比较会给出警告

Posted

技术标签:

【中文标题】将 Char 与 == 和单引号进行比较会给出警告【英文标题】:Comparing Char with == and single quote gives warning 【发布时间】:2020-12-13 09:14:29 【问题描述】:

我正在编写一个计算余弦的程序,我应该读取用户输入的角度(以度(°)或弧度(r)为单位)。如果角度以度为单位,则应将其转换为弧度(因此我使用了 if-else 语句)。但是,当我将 char 与 == 和单引号进行比较时,我收到以下警告:

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

这是我的完整代码:

#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);

【问题讨论】:

警告(多字符)告诉你,'°' 不是char 类型。 C 数据类型是在 UTF-8 和 Unicode 之前发明的。将char 视为“字节”的同义词。对于不在一个字节中表示的字符(例如处于 UTF-8 模式时的 º),您不能将它们存储在 char 中。您可以使用宽字符类型和实现定义的类型,或者设计自己的处理 Unicode 的方式(例如,使用 uint32_t 将 Unicode 代码点存储为 UCS-4)。 @goodvibration:在 C 中,没有字符常量是 char 类型的。他们都是int 【参考方案1】:

正如其他人在 cmets 中指出的那样,度 (°) 字符在 ASCII 系统中未编码为单个字节;相反,它被编译器解释为(可能)两个字节的序列。

有多种解决方法。一种方法是为您的unit 变量使用wchar_t 类型,并为比较使用相应的宽文字(L'°'L'r',代替'°''r');但是,这需要更改(至少)您的 scanf 调用以使用 %lc 格式说明符,但在这种情况下,您几乎肯定会更好,使用 wprintfwscanf“宽字符" 标准 I/O 函数的版本。

但是,即使进行了此类更改,您也可能会在控制台应用程序中读取° 字符时遇到问题,因为可以使用许多不同的编码系统。因此,在我看来,您最好使用一个简单的字母d 来指定度数单位。

此外,即使有任何这些修复,您的代码中也存在一些其他问题。最值得注意的是您正在测试unit 变量before。更正此问题的代码以及其他一些改进建议(并使用d 表示度数)如下所示:

#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);

请随时要求任何进一步的澄清和/或解释。

【讨论】:

【参考方案2】:

在 C 中,char 是一个字节,但度数符号通常需要一个以上的字节,至少在 UTF-8 字符编码中是这样。一种解决方案是将单位存储在字符数组中,如下所示:

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

int main(void)

    char unit[4 + 1];
    int count;

    count = scanf("%4s", unit);
    if (count == 1) 
        if (strcmp(unit, "°") == 0) 
            puts("degrees chosen");
         else if (strcmp(unit, "r") == 0) 
            puts("radians chosen");
         else 
            fprintf(stderr, "invalid unit: %s\n", unit);
            exit(EXIT_FAILURE);
        
    
    return 0;

UTF-8 字符的长度为一到四个字节,格式说明符 %4s 确保最多读取四个字节。

不过,更简单的方法是使用字母“d”来表示度数。

【讨论】:

以上是关于将 Char 与 == 和单引号进行比较会给出警告的主要内容,如果未能解决你的问题,请参考以下文章

读取带有双引号和单引号变量的 CSV 文件

unicode char 与非 unicode char 比较,但没有警告也没有错误

在 Xpath 中同时转义双引号和单引号

javascript中双引号和单引号之间的歧义

PHP双引号和单引号引起麻烦

Mysql中反引号和单引号的区别