由EOF和NULL引起的一个C程序的分析

来源:互联网 发布:淘宝活性炭都是假的吗 编辑:程序博客网 时间:2024/05/22 04:29

看一个程序,这个程序在执行时会出现无限循环:

#include<stdio.h>

#include<conio.h>

void main()

{

     char c;  

     FILE *fp;

    

       if((fp=fopen("c://wlj.cpp","r"))==NULL)

       printf("error");

    

       while((c=fgetc(fp))!=NULL) /*while((c=fgetc(fp))!=EOF) */

            printf("%c",c);

       fclose(fp);

    

       c = 255;  

       printf("%d %d",sizeof(short),c);

       getch();

}

分析:

1.       这个程序在执行会出现死循环,因为文件结尾会返回EOF=-1,而NULL被定义为00L((void *)0),所以正确的NULL改为EOF

参考:

/Vc7/include/stdio.h

/* Define NULL pointer value */

#ifndef NULL

#ifdef  __cplusplus

#define NULL    0

#else

#define NULL    ((void *)0)

#endif

#endif

 

/**/

#define EOF     (-1)

 

/TC/include/stdio.h

/**/

#ifndef NULL

#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)

#define NULL    0

#else

#define NULL    0L

#endif

#endif

 

/* End-of-file constant definition

*/

#define EOF     (-1)                    /* End of file indicator */

2.       TC2.0TC3.0VC7.0中单步调试代码时可以设定观察变量c(int)c,可以发现遇到回车换行符是读出的c=’/n’ (int)c=10,即ASCII中的LF(line feed),且仅仅是一个LF字符,没有CR (13)字符,这在写给文本加解密的程序时时要注意的,大二时写过对txt文件用异或算法加解密的程序,但是后来却发现解密(还原)后的文件有乱码,其实就是对回车换行符处理出了错误。

3.       遇到EOF字符时结果有些不同:

         

c

(int)c

TC2.0

‘ ‘

-1

TC3.0

‘ ‘

255

VC7.0

‘ ‘

-1

       由此可以看出,在三种环境中char类型有类似如下的定义

TC2.0

#define char signed short

TC3.0

#define char unsigned short

VC7.0

#define char signed byte

4.       getc不可能返回NULL(0)字符。

5.       此程序的最开始版本是

#include<stdio.h>

#include<conio.h>

void main()

{

     char a[1000],c;

     int i=0,j;

     FILE *fp;

     if((fp=fopen("c://my.cpp","r"))==NULL)

    printf("error");

     while((c=fgetc(fp))!=NULL) a[i++]=c;

     for(j=0;j<=i-1;j++)   printf("%c",a[j]);

    fclose(fp);

     getch();

}

这样的话程序更容易出错,因为boldfaced代码行出现无限循环时,数组a会出现越界,而C/C++没有数组越界检查,这样会造成内存的错误使用而使程序非法终止。

 

原创粉丝点击