当前位置:  开发笔记 > 编程语言 > 正文

从stdio文件写入函数处理返回值有什么好的编程模式

如何解决《从stdio文件写入函数处理返回值有什么好的编程模式》经验,为你挑选了2个好方法。

我正在研究一些产生大量代码的代码

ignoring return value of ‘size_t fwrite(const void*, size_t, size_t, FILE*)’, declared with attribute warn_unused_result

使用g ++编译时出现警告,我想知道实际记录和处理大量单独顺序fwrites 的返回值的最佳编程模式(即fwrite在循环中不一样)

让我们说代码现在看起来像这样:

fwrite (&blah, sizeof (blah), 1, fp);
// ... more code ...
fwrite (&foo, sizeof (foo), 1, fp);
// ... more code ...

我正在考虑这样的事情,但我可能很难清理文件指针:

if (fwrite (&blah, sizeof (blah), 1, fp) != 1) return someerrorcode;
// ... more code ...
if (fwrite (&foo, sizeof (foo), 1, fp) != 1) return someerrorcode;
// ... more code ...

我认为这种方法显然比嵌套更好,这太疯狂了:

if (fwrite (&blah, sizeof (blah), 1, fp) == 1) {
   // ... more code ...
   if (fwrite (&foo, sizeof (foo), 1, fp) == 1) {;
      // ... more code ...
   }
}

当然,对于这种事情,已经有了既定的最佳实践模式?

当然,因为我主要研究这个以摆脱编译器警告,我可以将返回值分配给虚拟变量并忽略它,但我想先尝试以正确的方式进行.

dummy = fwrite (&blah, sizeof (blah), 1, fp);
// ... more code ...
dummy = fwrite (&foo, sizeof (foo), 1, fp);
// ... more code ...

更新:我删除了c ++标签,因为这段代码实际上只是用g ++编译,所以需要基于c的解决方案来保持代码库的其余部分.



1> fbonnet..:

基于goto的穷人的C异常处理(实际上,goto的唯一实例不是有害的):

int foo() {
    FILE * fp = fopen(...);
    ....

    /* Note: fwrite returns the number of elements written, not bytes! */
    if (fwrite (&blah, sizeof (blah), 1, fp) != 1) goto error1;

    ...

    if (fwrite (&foo, sizeof (foo), 1, fp) != 1) goto error2;

    ...

ok:
    /* Everything went fine */
    fclose(fp);
    return 0;

error1:
    /* Error case 1 */
    fclose(fp);
    return -1;

error2:
    /* Error case 2 */
    fclose(fp);
    return -2;
}

你明白了.根据需要进行重组(单次/多次返回,单次清理,自定义错误消息等).根据我的经验,这是最常见的C错误处理模式.关键点是:永远不要忽略stdlib返回代码,任何这样做的好理由(例如可读性)都不够好.



2> Christoph..:

我会沿着这些方向做点什么:

FILE * file = fopen("foo", "wb");
if(!file) return FAILURE;

// assume failure by default
_Bool success = 0;

do
{
    if(!fwrite(&bar, sizeof(bar), 1, file))
        break;

    // [...]

    if(!fwrite(&baz, sizeof(baz), 1, file))
        break;

    // [...]

    success = 1;
} while(0);

fclose(file);

return success ? SUCCESS : FAILURE;

带着一点点C99宏魔法

#define with(SUBJECT, FINALIZE, ...) do { \
    if(SUBJECT) do { __VA_ARGS__ } while(0); if(SUBJECT) FINALIZE; \
} while(0)

并且使用ferror()Jonathan Leffler建议的代替我们自己的错误标志,这可以写成

FILE * file = fopen("foo", "wb");
with(file, fclose(file),
{
    if(!fwrite(&bar, sizeof(bar), 1, file))
        break;

    // [...]

    if(!fwrite(&baz, sizeof(baz), 1, file))
        break;

    // [...]
});

return file && !ferror(file) ? SUCCESS : FAILURE;

如果除了io错误之外还有其他错误条件,您仍然必须使用一个或多个错误变量跟踪它们.

此外,您的检查sizeof(blah)是错误的:fwrite()返回写入的对象的数量!

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有