繁体   English   中英

char的unicode误用于int

[英]unicode of char misused for int

我正在编写一个程序来读取学生成绩,无论是char还是int ,并将其存储在union ,然后打印成绩为A或> 90的学生。

但是当我尝试这样做时,我得到一个意外的输出,因为程序不知道我要比较哪一个(char或int)。

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

union StuGrade {
    char charGrade;
    int intGrade;
};

struct Student {
    int ID;
    int typeOfGrade;
    union StuGrade grade;
};

int main () {
    const int size = 5; 
    struct Student *sList[size]; 

    for (int i = 0; i < size; i++) {
        sList[i] = (struct Student *)calloc(1, sizeof(struct Student));
        if (!sList[i]) {
            puts("Error allocating memory");
            return 1;
        }
        printf("Enter ID: "); 
        scanf("%d", &(sList[i]->ID)); 
        printf("0 for char grade or 1 for int grade: "); 
        scanf("%d", &(sList[i]->typeOfGrade));

        if (sList[i]->typeOfGrade) { 
            printf("Enter an int grade: ");
            scanf("%d", &(sList[i]->grade.intGrade)); 
        } else { 
            printf("Enter a char grade: ");
            scanf(" %c", &(sList[i]->grade.charGrade)); 
        }
    } //end for loop

    printf("\n***Student(s) who take grade 'A' is/are***\n");
    for (int i = 0; i < size; i++) {
        if (sList[i]->grade.charGrade == 'A') 
            printf("ID: %d \nGrade: %c \n", sList[i]->ID, sList[i]->grade.charGrade);
        else if (sList[i]->grade.intGrade >= 90) 
            printf("ID: %d \nGrade: %d \n", sList[i]->ID, sList[i]->grade.intGrade);
    }
    for (int i = 0; i < size; i++)
        free(sList[i]);
    return 0;
}

这是输出:

Enter ID: 1
0 for char grade or 1 for int grade: 0
Enter a char grade: A
Enter ID: 2
0 for char grade or 1 for int grade: 0
Enter a char grade: b
Enter ID: 3
0 for char grade or 1 for int grade: 1
Enter an int grade: 99
Enter ID: 4
0 for char grade or 1 for int grade: 1
Enter an int grade: 84
Enter ID: 5
0 for char grade or 1 for int grade: 1
Enter an int grade: 65

***Student(s) who take grade 'A' is/are***
ID: 1 
Grade: A 
ID: 2 
Grade: 98 
ID: 3 
Grade: 99 
ID: 5 
Grade: A 

在比较中使用等级类型:

  if (sList[i]->typeOfGrade == 0 && sList[i]->grade.charGrade == 'A') 
     printf("ID: %d \nGrade: %c \n", sList[i]->ID, sList[i]->grade.charGrade);
  else if (sList[i]->typeOfGrade == 1 && sList[i]->grade.intGrade >= 90) 
     printf("ID: %d \nGrade: %d \n", sList[i]->ID, sList[i]->grade.intGrade);

注意:我的原始答案使用了ASCII表 ,但有人指出我应该使用UTF-8表 但是,两者都非常类似于此处描述的目的。 但是,技术上的编译器通常会使用UTF-8而不是ASCII,所以我编辑了我的答案来反映这一点。

Ville-Valtteri有一个非常好的答案,但我想解释一下发生了什么。

所以,请查看UTF-8表

希望您应该知道,任何计算机上的每个角色都会被翻译成一个数字。 这由上述表格确定。

在C和C ++中,如果我为一个char分配一个数字,那么它们在某种意义上是同等对待的:

char c = 65;

它将它视为字母'A'

相反,如果我将字母'A'分配给int:

int i = int('A');

你的结果是65

好的,现在你的代码。 让我们看看你的第一个测试:

if (sList[i]->grade.charGrade == 'A')

您测试以查看值是否= = 'A' 请注意,您不检查类型,因此65对于此测试是完全可以接受的, 即使您将其添加为int也是因为您没有对此进行测试。 测试'A'或等值65

现在,你的第二次测试:

else if (sList[i]->grade.intGrade >= 90) 

那么,如果它不是一个字母等级'A',它必须是一个int等级的权利? 错了,因为没有测试它是否是一个char等级,只是它不是char等级'A'。 没有那个,你接受这个测试。

这意味着字母'b'将进入此测试,其值为98 (再次参见UTF-8表 )。 由于C和C ++将数字和字母视为相同(不是技术上,但是接近),因此它将测试为98级,即使它是一个char等级。 这意味着它通过你> = 90检查。

这将我们带到Ville-Valtteri的解决方案 ,这将考虑到支票中的等级类型。

  if (sList[i]->typeOfGrade == 0 && sList[i]->grade.charGrade == 'A') printf("ID: %d \\nGrade: %c \\n", sList[i]->ID, sList[i]->grade.charGrade); else if (sList[i]->typeOfGrade == 1 && sList[i]->grade.intGrade >= 90) printf("ID: %d \\nGrade: %d \\n", sList[i]->ID, sList[i]->grade.intGrade); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM