首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一般情况下,包装ungetc()时不使用put()、get()和stream

一般情况下,包装ungetc()时不使用put()、get()和stream
EN

Stack Overflow用户
提问于 2016-11-16 23:40:13
回答 1查看 76关注 0票数 0

我正在将net-snmp移植到一个只能有限访问文件系统的嵌入式平台上,我偶然发现了一个大问题。核心代码中有一部分使用了ungetc()函数,而我没有。当然有两种解决方案:

A)使用我拥有的东西编写我自己的ungetc()

B)修改net-snmp代码,以在不使用ungetc()的情况下获得相同的结果

解决方案(B)最终将在net-snmp coders邮件列表中讨论,因为需要对库的内部结构有深入的了解,所以让我们重点关注(A)的可行性

我在我的嵌入式系统上有:

代码语言:javascript
复制
fopen()
fclose()
fcreate()
fwrite()
fread()
fdelete()
fclear()
fcopy()
ffindfirst()
ffindnext()
frename()
fgetsize()
ftell()
fseek()
fgetc()
fgets()

主要区别在于我的文件函数使用INT32*文件句柄,而不是文件*类型。我没有文件*类型。

ungetc()函数所做的基本上就是“把char放回流中”,要么是它刚刚读取的char,要么是另一个。

在第一种情况下,解决方案很简单,我使用fseek()将指针向后倒回一个位置。

但在第二种情况下,我遇到了一个问题。我会修改流而不是文件,除非我没有流!我正在直接读取文件。

使用ungetc(),您可以执行以下操作

代码语言:javascript
复制
FILE *fp = fopen("file.txt", "r");
int c = getc (fp);
if( c == 'a' ) ungetc ('b', fp);

如果"file.txt“包含"abcdefghi",则使用gets()的后续读取将读取"bbcdefghi”而不是"abcdefghi“,因为流中的内容已更改,但文件没有更改!

如果我没有“流”,我怎么能复制这种行为呢?我的getc()和gets()是从一个INT32*文件句柄读取的,而我没有对应的put()或putc()函数。

我只能用fwrite()写,但这会改变NV内存上的内容。

感谢您的见解

EN

回答 1

Stack Overflow用户

发布于 2016-11-28 19:21:50

下面是我解决这个问题的方法。我为文件句柄创建了一个更复杂的结构,它不仅包含句柄本身,还包含文件名、文件大小和一个保存整个文件内容的缓冲区。它应该只加载我需要的那部分文件,但我的是一个嵌入式应用程序,我知道我不会打开大文件,所以我没有麻烦。

然后,一旦你有了“流”,就很容易弹出字符。

代码语言:javascript
复制
typedef struct _myfile {
      _FS_HANDLE        handle; /* file descriptor */
      CHAR*             fname;  /* file name */
      UINT32            fsize;  /* file size */
      CHAR*             buffer; /* file buffer */
  } *my_FILE;

int my_ungetc(int c, my_FILE stream)
{
    if (stream)
    {
        UINT32 pointer = _fs_tell(stream->handle);
        if (pointer > 0)
        {
            _fs_seek(stream->handle,pointer - 1);
            stream->buffer[pointer - 1] = c;
            return c;
        }
    }
    else
    {
        printf("ERROR! stream is NULL!\r\n");
    }
    return EOF;
}

void *my_fopen(const char *filename, const char *mode)
{
    my_FILE fp = _mem_alloc(sizeof(struct _myfile));
    fp->fname = strdup(filename);
    if (mode == "r")
    {
        fp->handle = _fs_open((CHAR*)filename, OPEN_READ);
        if (fp->handle) fp->fsize = _get_size_with_handle(fp->handle);
        if (fp->fsize)
        {
            fp->buffer = _mem_alloc(fp->fsize);
            if (fp->buffer)
            {
                if (_fs_read(fp->handle,fp->buffer,fp->fsize))
                {
                    _fs_seek(fp->handle,0);
                }
                else
                {
                    printf("ERROR: unable to read %d bytes from %s\r\n",fp->fsize,filename);
                }
            }
            else
            {
                printf("ERROR in my_fopen(\"%s\",\"r\"): could not alloc %d bytes for buffer\r\n",filename,fp->fsize);
            }
        }
        else
        {
            fp->buffer = NULL;
            printf("File \"%s\" is empty\r\n");
        }
        return fp;
    }
    else if (mode == "w")
    {
        fp->handle = _fs_open((CHAR*)filename, OPEN_WRITE);
        if (fp->handle) fp->fsize = _get_size_with_handle(fp->handle);
        fp->buffer = NULL;
        return fp;
    }
    else
    {
        printf("File open mode %s not supported\r\n",mode);
        return NULL;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40636180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档