主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

字符值被吸收转化为 EOF

数据类型转换使有效的字符值与文件结尾 (EOF) 相同。

描述

当执行数据类型转换时,如果有效字符值与 EOF(文件末尾)无法区分,就会出现此缺陷。在以下情况下,Bug Finder 会标记缺陷:

  • 文件结尾:您执行数据类型转换,例如从 intchar,将非 EOF 字符值转换为 EOF

    char ch = (char)getchar()
    然后将结果与 EOF 进行比较。
    if((int)ch == EOF)
    转换可以是显式的,也可以是隐式的。

  • 宽文件结尾:执行数据类型转换,将非 WEOF 宽字符值转换为 WEOF,然后将结果与 WEOF 进行比较。

风险

数据类型 char 不能保存表示文件结束的值 EOF。诸如 getchar 之类的函数具有返回类型 int,以适应 EOF。如果将 int 转换为 char,则值 UCHAR_MAX(一个有效的字符值)和 EOF 将转换为相同的值 -1,从而无法区分彼此。当您将此转换的结果与 EOF 进行比较时,比较可能会导致错误地检测到 EOF。此原理也适用于宽字符值和 WEOF

修复

在转换前,先使用 EOFWEOF 进行比较。

示例

全部展开

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

char func(void)
{
    char ch;
    ch = getchar();
    if (EOF == (int)ch) {
        fatal_error();
    }
    return ch;
}

在此示例中,getchar 的返回值被隐式转换为 char。如果 getchar 返回 UCHAR_MAX,则将其转换为 -1,这与文件结尾标志 (EOF) 无法区分。当合法性后来与文件结尾 (EOF) 进行比较时,可能会导致错误的正匹配。

更正 - 在转换前与文件末尾进行比较

一种可能的更正方法是,首先使用 EOF 进行比较,然后将 int 转换为 char

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

char func(void)
{
    int i;               
    i = getchar();       
    if (EOF == i) {      
        fatal_error();
    }
    else {
        return (char)i;
    }
}

结果信息

组:编程
语言:C | C++
默认值:手写代码时为启动,生成代码时为关闭
命令行语法:CHAR_EOF_CONFUSED
影响

版本历史记录

在 R2017a 中推出