我将net-snmp移植到一个只能访问文件系统的嵌入式平台上,我偶然发现了一个大问题。核心代码的一部分使用ungetc()函数,我没有。当然有两种解决方案:
A)使用我拥有的东西编写自己的ungetc()
B)修改net-snmp代码,以便在没有ungetc()
的情况下实现相同的结果解决方案(B)最终将在net-snmp编码器邮件列表中讨论,因为需要深入了解库的内部,所以请关注(A)的可行性
我的嵌入式系统有:
fopen()
fclose()
fcreate()
fwrite()
fread()
fdelete()
fclear()
fcopy()
ffindfirst()
ffindnext()
frename()
fgetsize()
ftell()
fseek()
fgetc()
fgets()
主要区别在于我的文件函数使用INT32 *文件句柄而不是FILE *类型。我没有FILE *类型。
ungetc()函数的作用基本上是"将char放回流中#34; ,或者它刚读过的字符或另一个字符。
在第一种情况下解决方案很简单,我用fseek()向后倒回指针。
但在第二种情况下我遇到了问题。我会修改流而不是文件,除了我没有流!我直接读了这个文件。
使用ungetc(),您可以执行类似
的操作FILE *fp = fopen("file.txt", "r");
int c = getc (fp);
if( c == 'a' ) ungetc ('b', fp);
如果" file.txt"包含" abcdefghi",随后用gets()读取将读取" bbcdefghi"而不是" abcdefghi"因为STREAM中的内容已被更改,但不是文件!
如果我没有" stream"我怎样才能复制这种行为? ?我的getc()和gets()从INT32 *文件句柄读取,我没有put()或putc()等价。
我只能使用fwrite()编写,但会改变NV内存中的内容。
感谢您的见解
答案 0 :(得分:0)
以下是我如何解决它。我为文件句柄创建了一个更复杂的结构,它不仅包含句柄本身,还包含文件名,文件大小和保存文件整个内容的缓冲区。它应该只加载我需要的文件部分,但我的是一个嵌入式应用程序,我知道我不会打开大文件所以我没有打扰。
然后,一旦你有"流"进出的流行歌词很简单。
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;
}
}