c-如何只使用fread()和vsscanf()包装fscanf()



我正在使用类似C的API的嵌入式平台上移植一些代码。原始代码使用fscanf()从文件中读取和解析数据。不幸的是,在我的API上,我没有fscanf()等价物,所以在实际移植之前,我试图使用fread()vsscanf()(我确实有)获得fscanf()的相同行为。我还有fseek()ftell()的等价物。

EDIT:请记住,对嵌入式文件系统的访问非常有限(fread-fsek-ftell-fgets-fgets),因此我需要一个处理内存中字符串的解决方案,而不是以其他方式访问文件。

代码看起来像这样:

int main()
{
[...] /* variable declarations and definitions */
do
{
read = wrapped_fscanf(pFile, "%d %s", &val, str);
} while (read == 2);
fclose(pFile);
return 0;
}
int wrapped_fscanf(FILE *f, const char *template, ...)
{
va_list args;
va_start(args, template);
char tmpstr[50];
fread(tmpstr, sizeof(char), sizeof(tmpstr), f);
int ret = vsscanf(tmpstr, template, args);
long offset = /* ??? */
fseek(f, offset, SEEK_CUR);
va_end(args);
return ret;
}

问题是fscanf()将指针移到匹配结束时文件流中的位置,而使用fread(),我读取的数据量固定(在本例中为50字节),我应该找到将指针移回匹配字符串末尾的方法。

假设我从文件中读取的50个字符的字符串如下:

12 bar13 foo 5678901234567890123456789012345 6789

fscanf()将与int12匹配,字符串bar和指针将直接指向"bar"中的"r"之后,因此我可以再次调用它并读取13 foo

另一方面,fread()将指针放在50元素序列中的最后一个字符之后,这是错误的:我仍然必须读取13 foo,但如果我再次调用wrapped_fscanf(),指针就在第51个位置。

我必须使用fseek()才能回到第一场比赛的最后,但我该怎么做呢?如何计算offset的值?

vsscanf()返回匹配的数量,而不是字符串的长度,我无法知道有多少空白字符分隔了匹配的元素(还是I?)

也就是说,我得到了与相同的输出({var,str,read}=={9,"xyz",2})

9 xyz

9          xyz

除了用fread()vsscanf()ftell()fseek()包装fscanf()之外,还有什么我不知道的技巧吗?

谢谢

假设vsscanf()实现支持它,那么fscanf()的替代品可以在所提供格式的末尾附加一个%n字段描述符。只要在vsscanf()到达该字段之前没有失败,它就会在相应的参数中存储到该点为止消耗的字符数。然后,您可以使用该结果来适当地重新定位流。这需要一些varargs的争论,可能还需要一些宏观援助,但我认为这是可行的。

您将需要一些中间缓冲代码,它将抓取数据块(使用fread),并扫描缓冲区以查找模式。如果找到了模式,则截断缓冲区;如果找不到模式,则追加更多数据。这实际上就是fscanf要做的。

相关内容

  • 没有找到相关文章

最新更新