【发布时间】:2021-07-10 12:12:40
【问题描述】:
我正在尝试实现fopen、fclose、fputc和fgetc等模拟文件系统。
一切都很好,除了写作(关闭时)。
当它使用 myfclose 关闭时,我想将缓冲区中剩余的字符(如果有的话)写入文件。但它返回错误 -1,Bad file descriptor。
另一方面,如果我在 myfclose 函数中打开并新写入另一个文件,则没有问题。
我不知道它有什么问题。
代码如下:
我的文件.c
#include "mystdio.h"
int main()
{
char c;
MYFILE *fpin, *fpout;
if((fpin = myfopen("a", "r")) == NULL) {
perror("a");
exit(-1);
}
if ((fpout = myfopen("b", "w")) == NULL) {
perror("b"); exit(-1);
}
while((c = myfgetc(fpin)) != EOF) {
myfputc(c, fpout);
}
myfclose(fpin); myfclose(fpout);
}
mystdio.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define BUFSIZE 1024
#define READONLY_MODE 0
#define WRITEONLY_MODE 1
typedef struct {
int fd;
char mode;
char buf[BUFSIZE];
int length;
int offset;
} MYFILE;
MYFILE *myfopen(char *file, char *mode);
int myfclose(MYFILE *fp);
char myfgetc(MYFILE *fp);
void myfputc(char c, MYFILE *fp);
MYFILE *myfopen(char *file, char *mode)
{
MYFILE *fp = (MYFILE *)malloc(sizeof(MYFILE));
if (fp != NULL) {
// read mode
if (strcmp(mode, "r") == 0) {
if ((fp->fd = open(file, O_RDONLY)) < 0) {
free(fp);
return NULL;
}
fp->mode = READONLY_MODE;
}
else if (strcmp(mode, "w") == 0) {
if ((fp->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
free(fp);
return NULL;
}
fp->mode = WRITEONLY_MODE;
}
else {
fprintf(stderr, "not supported mode: %s\n", mode);
free(fp);
return NULL;
}
fp->length = fp->offset = 0;
}
return fp;
}
int myfclose(MYFILE *fp)
{
if (fp == NULL) return EOF;
if (close(fp->fd) < 0) {
free(fp);
return EOF;
}
if (fp->mode == 1) {
if (fp->length > fp->offset) {
char buf[fp->offset - 1];
memcpy(buf, fp->buf, (fp->offset - 1));
buf[fp->offset - 1] = '\0';
printf("%d %s %lu\n", fp->fd, buf, sizeof(buf));
// ERROR CODE: return bad descriptor
if ((write(fp->fd, &buf, strlen(buf))) != strlen(buf)) {
perror("Write");
}
}
}
free(fp);
return 0;
}
char myfgetc(MYFILE *fp)
{
if (fp == NULL) return EOF;
if (fp->offset == fp->length) {
if ((fp->length = read(fp->fd, fp->buf, BUFSIZE)) < 1) return EOF;
fp->offset = 0;
}
return fp->buf[fp->offset++];
}
void myfputc(char c, MYFILE *fp)
{
if (fp == NULL) exit(-1);
fp->length = BUFSIZE;
if (fp->offset == fp->length) {
if ((write(fp->fd, fp->buf, BUFSIZE)) < BUFSIZE) {
fprintf(stderr, "failed to write");
exit(-1);
}
fp->offset = 0;
}
fp->buf[fp->offset++] = c;
}
【问题讨论】:
-
这是开始学习调试器基本用法的好机会。你将花一个小时左右的时间来学习这将很快得到回报。
-
您正在关闭文件描述符,然后写入它(
myfclose)。这永远不会奏效。 -
@Jabberwocky TBH,我认为调试器在这里不会有太大帮助。但你说得对,它是一个有用的工具。
标签: c linux file system-calls write