簡體   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