关于c程序中的myfopen()怎么解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (46)
  1. 在myfopen()函数中,有一个for循环; 我不明白的是,fp将从_iob开始有值,但我没有得到fp-> flag在第一个三个值(已被修复)之后会取得的值。他们会采取零值,他们说我们必须使用malloc来为fp提供内存空间,但fp已经提供了内存空间,因为_iob数组有空间并且fp会继续使用数组元素的地址,所以malloc的需要是什么?
  2. 其次,在main()函数中,提到的模式是“r”,但后缀使用的系统调用是write(),尽管它不显示错误,但为什么这可能呢?
  3. 第三,编译器在编译此代码时不显示错误或警告,但显示一个对话框,指出“f_open.exe已停止工作”,即使我们编写malloc行(或不编写),或者即使存在“r”模式或“w”模式。那么,什么是错的?
#include<fcntl.h> #include<unistd.h> #include<stdlib.h> #define PERM 0644 #define EOF (-1) #define BUFSIZE 1024 #define OPEN_MAX 20  typedef struct _iobuf{     int cnt;     char *ptr;     char *base;     int flag;     int fd; } myFILE;  enum _flags {     _READ   = 01,     _WRITE  = 02,     _UNBUF  = 04,     _EOF    = 010,     _ERR    = 020 };  myFILE _iob[OPEN_MAX]={     {0, (char *) 0, (char *) 0, _READ, 0 },     {0, (char *) 0, (char *) 0, _WRITE, 1 },     {0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 } };  #define stdin (&_iob[0]) #define stdout (&_iob[1]) #define stderr (&_iob[2])  #define getc(p)     ( --(p)->cnt>=0 ? (unsigned char) *(p)->ptr++ : _fillbuf(p) )  int _fillbuf(myFILE *fp) {     int bufsize;      if((fp->flag & (_READ|_EOF|_ERR))!=_READ)         return EOF;      bufsize=(fp->flag & _UNBUF)? 1 : BUFSIZE;      if(fp->base==NULL)         if((fp->base=(char *)malloc(bufsize))==NULL)             return EOF;      fp->ptr=fp->base;      fp->cnt=read(fp->fd, fp->ptr, bufsize);      if(--fp->cnt<0){         if(fp->cnt == -1)             fp->flag |= _EOF;         else             fp->flag |= _ERR;         return EOF;     }     return (unsigned char) *fp->ptr++;   }  myFILE *myfopen(char *name, char *mode) {     int fd;     myFILE *fp;      if(*mode!='r' && *mode!='w' && *mode!='a')           return NULL;     for(fp=_iob; fp<_iob+OPEN_MAX; fp++)         if((fp->flag & (_READ | _WRITE))==0)             break;      if(fp>=_iob+OPEN_MAX)         return NULL;      if(*mode=='w')          fd=creat(name, PERM);     else if(*mode=='a'){         if((fd=open(name, O_WRONLY, 0))==-1)             fd=creat(name, PERM);            lseek(fd, 0L, 2);     } else         fd=open(name, O_RDONLY, 0);      if(fd==-1)         return NULL;      fp->fd = fd;     fp->cnt = 0;     fp->base = NULL;     fp->flag = (*mode=='r')? _READ : _WRITE;          return fp;         }   int main(int argc, char *argv[]) {     myFILE *fp;    int c;      if((fp=myfopen(argv[1], "r"))!=NULL)         write(1, "opened\n", sizeof("opened\n"));       while((c=getc(fp))!=EOF)           write(1, &c, sizeof(c));      return 0; } 

解决方案:

myFILE *fp;

if(*mode!='r' && *mode!='w' && *mode!='a')
      return NULL;
for(fp=_iob; fp<_iob+OPEN_MAX; fp++)
    if((fp->flag & (_READ | _WRITE))==0) // marked line
        break;

提供的解决方案是

myFILE *fp;

if(*mode!='r' && *mode!='w' && *mode!='a')
      return NULL;
for(fp=_iob; fp<_iob+OPEN_MAX; fp++)
    if((fp->flag & (_READ | _WRITE))==0) // marked line
        break;

这是你需要改变的。

myFILE *fp = (myFILE *)malloc(sizeof(myFILE));

一定要#include使用malloc。

提问于
用户回答回答于

该循环中的myfopen()内容如下:

for (fp =_iob; fp <_iob + OPEN_MAX; fp++)
    if ((fp->flag & (_READ | _WRITE)) == 0)
        break;

是完全正确的。它遍历数组的元素_iob,并且永远不会像声明的那样遇到空指针。缓冲区_iob初始化为前三个元素; 其余全部为零。

麻烦的可能原因

此程序崩溃的最可能原因是:

  1. 没有提供参数文件的名称。
  2. 提供的名称不能打开以供阅读。

显示的代码main()是:

int main(int argc, char *argv[])
{
    myFILE *fp;
   int c;

    if((fp=myfopen(argv[1], "r"))!=NULL)
        write(1, "opened\n", sizeof("opened\n"));

     while((c=getc(fp))!=EOF)
          write(1, &c, sizeof(c));

    return 0;
}

代码不检查这些常见问题。它应该更像是:

int main(int argc, char *argv[])
{
    myFILE *fp;
    int c;

    if (argc != 2)
    {
        static const char usage[] = "Usage: mystdio filename\n";
        write(2, usage, sizeof(usage)-1);
        return 1;
    }

    if ((fp = myfopen(argv[1], "r")) == NULL)
    {
        static const char filenotopened[] = "mystdio: failed to open file ";
        write(2, filenotopened, sizeof(filenotopened)-1);
        write(2, argv[1], strlen(argv[1]);
        write(2, "\n", 1);
        return 1;
    }

    write(1, "opened\n", sizeof("opened\n"));

    while ((c = getc(fp)) != EOF)
        write(1, &c, sizeof(c));

    return 0;
}

所属标签

可能回答问题的人

  • 天使的炫翼

    15 粉丝531 提问35 回答
  • 富有想象力的人

    2 粉丝0 提问26 回答
  • 旺仔小小鹿

    社区 · 运营 (已认证)

    48 粉丝0 提问26 回答
  • 发条丶魔灵1

    6 粉丝525 提问25 回答

扫码关注云+社区

领取腾讯云代金券